summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2024-02-26 13:58:18 +0100
committerMichael Stahl <michael.stahl@allotropia.de>2024-02-26 14:58:47 +0100
commit6eb71b1778d8bc44ec642f3e61096350e4c868dc (patch)
treeecf973d0d644ec8af66de3978e7a91fa2d123171
parent678b716506c20566167d19168f33aa94db7407e3 (diff)
sw: revert Select All improvements
Revert "tdf#157129 sw: fix wrong cursor position after paste" This reverts commit 68310c73c1755d2e8a4d6f80084ef3d6b7a1d10e. Revert "tdf#156546 sw: fix infinite loop in SwUndoInsert::RedoImpl()" This reverts commit e43f09bec7bc1d7f367a9b6f6a8ec001a102645d. Revert "tdf#156267 sw: remove DdeBookmarks in SwDoc::DelTable()" This reverts commit 20c272631877d2c77bd0b14fee41acfb056aade7. Revert "tdf#155685 sw: ExtendedSelectAll with tables, group the Undo objects" This reverts commit 1f1078e0cbcc5879128d20e0748b0dd1583a471e. Revert "tdf#155685 sw: fix another ExtendedSelectAll Redo crash w table at end" This reverts commit 15e494724ab728962f133eb8d81c5fcd475b9197. Revert "cool#6580 sw: fix infinite loop when changing document language" This reverts commit a7a1f426374f865ef31f5c5162eac4c1c11efc6c. Revert "tdf#155685 sw: fix crash on undo of ExtendedSelectAll with table at end" This reverts commit a2b206ec80119000c581aa954632a1a9839408ba. Revert "tdf#155346 sw: fix crash from changing modal mode" This reverts commit 86d9b8f6f353f5d268f67f2c33681b8fa4f46ea7. Revert "tdf#154877 sw: generalise ExtendedSelectAll()" This reverts commit 9667e5ffd18d6167344e102b89a393bc981644ec. Revert "sw: SelectAll should copy section before table at start of document" This reverts commit 53c9990152ef19b0a8d07fc514cef0a73496514c.
-rw-r--r--sw/inc/crsrsh.hxx14
-rw-r--r--sw/inc/doc.hxx1
-rw-r--r--sw/inc/undobj.hxx12
-rw-r--r--sw/qa/extras/odfimport/odfimport.cxx4
-rw-r--r--sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt219
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx22
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx18
-rw-r--r--sw/source/core/crsr/crsrsh.cxx321
-rw-r--r--sw/source/core/docnode/ndtbl.cxx287
-rw-r--r--sw/source/core/edit/eddel.cxx36
-rw-r--r--sw/source/core/edit/edglss.cxx14
-rw-r--r--sw/source/core/undo/undobj.cxx22
-rw-r--r--sw/source/core/undo/unins.cxx4
-rw-r--r--sw/source/core/undo/untblk.cxx6
-rw-r--r--sw/source/uibase/wrtsh/move.cxx46
-rw-r--r--sw/source/uibase/wrtsh/select.cxx36
16 files changed, 227 insertions, 835 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 26e6895e88cd..a0205ffe4d52 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -326,7 +326,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.
- ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>> ExtendedSelectedAll() const;
+ bool ExtendedSelectedAll();
enum class StartsWith { None, Table, HiddenPara };
/// If document body starts with a table or starts/ends with hidden paragraph.
StartsWith StartsWith_();
@@ -586,11 +586,8 @@ public:
// fields etc.
OUString GetSelText() const;
- /// Check if Point of current cursor is placed within a table.
- const SwTableNode* IsCursorInTable() const;
- bool MoveOutOfTable();
- bool TrySelectOuterTable();
- bool MoveStartText();
+ // Check of SPoint or Mark of current cursor are placed within a table.
+ inline const SwTableNode* IsCursorInTable() const;
bool IsCursorInFootnote() const;
@@ -904,6 +901,11 @@ inline bool SwCursorShell::IsMultiSelection() const
return m_pCurrentCursor->GetNext() != m_pCurrentCursor;
}
+inline const SwTableNode* SwCursorShell::IsCursorInTable() const
+{
+ return m_pCurrentCursor->GetNode().FindTableNode();
+}
+
inline bool SwCursorShell::IsCursorPtAtEnd() const
{
return m_pCurrentCursor->End() == m_pCurrentCursor->GetPoint();
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 66ec563e7a14..83651fc8fcb2 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1189,7 +1189,6 @@ public:
sal_uInt16 nCnt = 1, bool bBehind = true );
// Delete Columns/Rows in table.
- void DelTable(SwTableNode * pTable);
bool DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn = false );
void DeleteRow( const SwCursor& rCursor );
void DeleteCol( const SwCursor& rCursor );
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index 42b14f7859e5..71d9c511591d 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -21,7 +21,6 @@
#include <vector>
#include <memory>
-#include <optional>
#include <svl/undo.hxx>
#include <tools/solar.h>
@@ -178,11 +177,12 @@ protected:
const sal_uLong* pEndNdIdx = nullptr,
bool bForceCreateFrames = false);
- // These two methods save and restore the Point of PaM.
- // If the point cannot be moved, a "backup" is created on the previous node.
- // Either way, it will not be moved by inserting at its original position.
- static ::std::optional<SwNodeIndex> MovePtBackward(SwPaM& rPam);
- static void MovePtForward(SwPaM& rPam, ::std::optional<SwNodeIndex> && oMvBkwrd);
+ // These two methods move the SPoint back/forth from PaM. With it
+ // a range can be spanned for Undo/Redo. (In this case the SPoint
+ // is before the manipulated range!!)
+ // The flag indicates if there is content before the SPoint.
+ static bool MovePtBackward( SwPaM& rPam );
+ static void MovePtForward( SwPaM& rPam, bool bMvBkwrd );
// Before moving stuff into UndoNodes-Array care has to be taken that
// the content-bearing attributes are removed from the nodes-array.
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index dc9bc44679e6..3fa5321389e4 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -590,8 +590,6 @@ DECLARE_ODFIMPORT_TEST(testFdo37606, "fdo37606.odt")
pWrtShell->SelAll(); // Selects the whole table.
pWrtShell->SelAll(); // Selects the whole document.
- pShellCursor = pWrtShell->getShellCursor(false);
-
SwTextNode& rStart = dynamic_cast<SwTextNode&>(pShellCursor->Start()->nNode.GetNode());
CPPUNIT_ASSERT_EQUAL(OUString("A1"), rStart.GetText());
@@ -657,11 +655,11 @@ DECLARE_ODFIMPORT_TEST(testFdo69862, "fdo69862.odt")
SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
CPPUNIT_ASSERT(pTextDoc);
SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+ SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
pWrtShell->SelAll(); // Selects A1.
pWrtShell->SelAll(); // Selects the whole table.
pWrtShell->SelAll(); // Selects the whole document.
- SwShellCursor* pShellCursor = pWrtShell->getShellCursor(false);
SwTextNode& rStart = dynamic_cast<SwTextNode&>(pShellCursor->Start()->nNode.GetNode());
// This was "Footnote.", as Ctrl-A also selected footnotes, but it should not.
CPPUNIT_ASSERT_EQUAL(OUString("A1"), rStart.GetText());
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
deleted file mode 100644
index 4e18f7dc2ce4..000000000000
--- a/sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt
+++ /dev/null
@@ -1,219 +0,0 @@
-<?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-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 cdb6a3634552..3df7f5e8b75d 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -942,23 +942,6 @@ void SwUiWriterTest::testTdf67238()
CPPUNIT_ASSERT(!((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
}
-CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf155685)
-{
- SwDoc* pDoc = createDoc("table-at-end-of-cell.fodt");
- 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();
-}
-
void SwUiWriterTest::testFdo75110()
{
SwDoc* pDoc = createDoc("fdo75110.odt");
@@ -8099,7 +8082,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf133982)
lcl_dispatchCommand(mxComponent, ".uno:SelectAll", {});
lcl_dispatchCommand(mxComponent, ".uno:SelectAll", {});
lcl_dispatchCommand(mxComponent, ".uno:SelectAll", {});
- lcl_dispatchCommand(mxComponent, ".uno:SelectAll", {});
//Without the fix in place, it would have crashed here
lcl_dispatchCommand(mxComponent, ".uno:Cut", {});
@@ -8159,12 +8141,10 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf114973)
{
SwDoc* const pDoc = createDoc("tdf114973.fodt");
- SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
- pWrtShell->SttEndDoc(true);
-
lcl_dispatchCommand(mxComponent, ".uno:SelectAll", {});
Scheduler::ProcessEventsToIdle();
+ SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
// bug: cursor jumped into header
CPPUNIT_ASSERT(!pWrtShell->IsInHeaderFooter());
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 702efd1c2dff..f2a358d46b25 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -23,10 +23,6 @@
#include <i18nlangtag/languagetag.hxx>
#include <vcl/scheduler.hxx>
#include <vcl/settings.hxx>
-#include <sfx2/dispatch.hxx>
-#include <sfx2/viewfrm.hxx>
-#include <svx/svxids.hrc>
-#include <view.hxx>
#include <ndtxt.hxx>
#include <swdtflvr.hxx>
#include <wrtsh.hxx>
@@ -260,20 +256,6 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf101534)
CPPUNIT_ASSERT(aSet.HasItem(RES_LR_SPACE));
}
-CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testExtendedSelectAllHang)
-{
- SwDoc* const pDoc = createDoc();
- SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
-
- pWrtShell->InsertFootnote("");
- pWrtShell->StartOfSection();
- SwView* pView = pDoc->GetDocShell()->GetView();
- SfxStringItem aLangString(SID_LANGUAGE_STATUS, "Default_Spanish (Bolivia)");
- // this looped
- pView->GetViewFrame()->GetDispatcher()->ExecuteList(SID_LANGUAGE_STATUS, SfxCallMode::SYNCHRON,
- { &aLangString });
-}
-
CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineMoveInsertInDelete)
{
loadURL("private:factory/swriter", nullptr);
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index e58821c60808..2258d39a8422 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -581,322 +581,54 @@ bool SwCursorShell::SttEndDoc( bool bStt )
return bRet;
}
-const SwTableNode* SwCursorShell::IsCursorInTable() const
-{
- if (m_pTableCursor)
- { // find the table that has the selected boxes
- return m_pTableCursor->GetSelectedBoxes()[0]->GetSttNd()->FindTableNode();
- }
- return m_pCurrentCursor->GetNode().FindTableNode();
-}
-
-// fun cases to consider:
-// * outermost table
-// - into para => SA/ESA
-// - into prev/next table => continue...
-// - no prev/next => done
-// * inner table
-// - into containing cell => SA/ESA
-// - into prev/next of containing cell
-// + into para
-// + into table nested in prev/next cell
-// - out of table -> as above
-// => iterate in one direction until a node is reached that is a parent or a sibling of a parent of the current table
-// - parent reached => SA/ESA depending
-// - not in parent but in *prev/next* sibling of outer cell => TrySelectOuterTable
-// - not in parent but in *prev/next* sibling of outer table => TrySelectOuterTable
-// => select-all cannot select a sequence of table with no para at same level; only 1 table
-// - no parent, no prev/next => TrySelectOuterTable
-
-bool SwCursorShell::MoveOutOfTable()
-{
- SwPosition const point(*getShellCursor(false)->GetPoint());
- SwPosition const mark(*getShellCursor(false)->GetMark());
-
- for (auto const fnMove : {&fnMoveBackward, &fnMoveForward})
- {
- Push();
- SwCursor *const pCursor(getShellCursor(false));
-
- pCursor->Normalize(fnMove == &fnMoveBackward);
- pCursor->DeleteMark();
- SwTableNode const*const pTable(pCursor->GetPoint()->nNode.GetNode().FindTableNode());
- assert(pTable);
- while (MovePara(GoInContent, *fnMove))
- {
- SwStartNode const*const pBox(pCursor->GetPoint()->nNode.GetNode().FindTableBoxStartNode());
- if (!pBox)
- {
- Pop(SwCursorShell::PopMode::DeleteStack);
- return true; // moved to paragraph at top-level of text
- }
- if (pBox->GetIndex() < pTable->GetIndex()
- && pTable->EndOfSectionIndex() < pBox->EndOfSectionIndex())
- {
- Pop(SwCursorShell::PopMode::DeleteStack);
- return true; // pBox contains start position (pTable)
- }
- }
-
- Pop(SwCursorShell::PopMode::DeleteCurrent);
- // FIXME: Pop doesn't restore original cursor if nested tables
- *getShellCursor(false)->GetPoint() = point;
- getShellCursor(false)->SetMark();
- *getShellCursor(false)->GetMark() = mark;
- }
- return false;
-}
-
-bool SwCursorShell::TrySelectOuterTable()
-{
- assert(m_pTableCursor);
- SwTableNode const& rInnerTable(*m_pTableCursor->GetPoint()->nNode.GetNode().FindTableNode());
- SwNodes const& rNodes(rInnerTable.GetNodes());
- SwTableNode const*const pOuterTable(rInnerTable.GetNodes()[rInnerTable.GetIndex()-1]->FindTableNode());
- if (!pOuterTable)
- {
- return false;
- }
-
- // manually select boxes of pOuterTable
- SwNodeIndex firstCell(*pOuterTable, +1);
- SwNodeIndex lastCell(*rNodes[pOuterTable->EndOfSectionIndex()-1]->StartOfSectionNode());
- SwSelBoxes aNew;
- pOuterTable->GetTable().CreateSelection(&firstCell.GetNode(), &lastCell.GetNode(),
- aNew, SwTable::SEARCH_NONE, false);
- // set table cursor to 1st / last content which may be in inner table
- SwContentNode *const pStart = rNodes.GoNext(&firstCell);
- assert(pStart); // must at least find the previous point node
- lastCell = *lastCell.GetNode().EndOfSectionNode();
- SwContentNode *const pEnd = SwNodes::GoPrevious(&lastCell);
- assert(pEnd); // must at least find the previous point node
- delete m_pTableCursor;
- m_pTableCursor = new SwShellTableCursor(*this, SwPosition(*pStart, 0), Point(),
- SwPosition(*pEnd, 0), Point());
- m_pTableCursor->ActualizeSelection( aNew );
- m_pTableCursor->IsCursorMovedUpdate(); // clear this so GetCursor() doesn't recreate our SwSelBoxes
-
- // this will update m_pCurrentCursor based on m_pTableCursor
- UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
-
- return true;
-}
-
-/// find XText start node
-static SwStartNode const* FindTextStart(SwPosition const& rPos)
-{
- SwStartNode const* pStartNode(rPos.nNode.GetNode().StartOfSectionNode());
- while (pStartNode && (pStartNode->IsSectionNode() || pStartNode->IsTableNode()))
- {
- pStartNode = pStartNode->StartOfSectionNode();
- }
- return pStartNode;
-}
-
-static SwStartNode const* FindParentText(SwShellCursor const& rCursor)
-{
- // find closest section containing both start and end - ignore Sections
- SwStartNode const* pStartNode(FindTextStart(*rCursor.Start()));
- SwEndNode const* pEndNode(FindTextStart(*rCursor.End())->EndOfSectionNode());
- while (pStartNode->EndOfSectionNode()->GetIndex() < pEndNode->GetIndex())
- {
- pStartNode = pStartNode->StartOfSectionNode();
- }
- while (pStartNode->GetIndex() < pEndNode->StartOfSectionNode()->GetIndex())
- {
- pEndNode = pEndNode->StartOfSectionNode()->StartOfSectionNode()->EndOfSectionNode();
- }
- assert(pStartNode->EndOfSectionNode() == pEndNode);
-
- return (pStartNode->IsSectionNode() || pStartNode->IsTableNode())
- ? FindTextStart(SwPosition(*pStartNode))
- : pStartNode;
-}
-
-bool SwCursorShell::MoveStartText()
-{
- SwPosition const old(*m_pCurrentCursor->GetPoint());
- SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
- assert(pStartNode);
- SwTableNode const*const pTable(pStartNode->FindTableNode());
- *m_pCurrentCursor->GetPoint() = SwPosition(*pStartNode);
- GetDoc()->GetNodes().GoNext(&m_pCurrentCursor->GetPoint()->nNode);
- m_pCurrentCursor->GetPoint()->nContent.Assign(m_pCurrentCursor->GetPoint()->nNode.GetNode().GetContentNode(), 0);
- while (m_pCurrentCursor->GetPoint()->nNode.GetNode().FindTableNode() != pTable
- && (!pTable || pTable->GetIndex() < m_pCurrentCursor->GetPoint()->nNode.GetNode().FindTableNode()->GetIndex())
- && MoveOutOfTable());
- UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
- return old != *m_pCurrentCursor->GetPoint();
-}
-
-// select all inside the current XText, with table or hidden para at start/end
void SwCursorShell::ExtendedSelectAll(bool bFootnotes)
{
- // find common ancestor node of both ends of cursor
- SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
- assert(pStartNode);
- if (IsTableMode())
- { // convert m_pTableCursor to m_pCurrentCursor after determining pStartNode
- TableCursorToCursor();
- }
SwNodes& rNodes = GetDoc()->GetNodes();
- m_pCurrentCursor->Normalize(true);
SwPosition* pPos = m_pCurrentCursor->GetPoint();
- pPos->nNode = bFootnotes ? rNodes.GetEndOfPostIts() : static_cast<SwNode const&>(*pStartNode);
+ pPos->nNode = bFootnotes ? rNodes.GetEndOfPostIts() : rNodes.GetEndOfAutotext();
pPos->nContent.Assign( rNodes.GoNext( &pPos->nNode ), 0 );
pPos = m_pCurrentCursor->GetMark();
- pPos->nNode = bFootnotes ? rNodes.GetEndOfContent() : static_cast<SwNode const&>(*pStartNode->EndOfSectionNode());
+ pPos->nNode = rNodes.GetEndOfContent();
SwContentNode* pCNd = SwNodes::GoPrevious( &pPos->nNode );
pPos->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
}
-static typename SwCursorShell::StartsWith StartsWith(SwStartNode const& rStart)
-{
- for (auto i = rStart.GetIndex() + 1; i < rStart.EndOfSectionIndex(); ++i)
- {
- SwNode const& rNode(*rStart.GetNodes()[i]);
- switch (rNode.GetNodeType())
- {
- case SwNodeType::Section:
- continue;
- case SwNodeType::Table:
- return SwCursorShell::StartsWith::Table;
- case SwNodeType::Text:
- if (rNode.GetTextNode()->IsHidden())
- {
- return SwCursorShell::StartsWith::HiddenPara;
- }
- return SwCursorShell::StartsWith::None;
- default:
- return SwCursorShell::StartsWith::None;
- }
- }
- return SwCursorShell::StartsWith::None;
-}
-
-static typename SwCursorShell::StartsWith EndsWith(SwStartNode const& rStart)
-{
- for (auto i = rStart.EndOfSectionIndex() - 1; rStart.GetIndex() < i; --i)
- {
- SwNode const& rNode(*rStart.GetNodes()[i]);
- switch (rNode.GetNodeType())
- {
- case SwNodeType::End:
- if (rNode.StartOfSectionNode()->IsTableNode())
- {
- return SwCursorShell::StartsWith::Table;
- }
-//TODO buggy SwUndoRedline in testTdf137503? assert(rNode.StartOfSectionNode()->IsSectionNode());
- break;
- case SwNodeType::Text:
- if (rNode.GetTextNode()->IsHidden())
- {
- return SwCursorShell::StartsWith::HiddenPara;
- }
- return SwCursorShell::StartsWith::None;
- default:
- return SwCursorShell::StartsWith::None;
- }
- }
- return SwCursorShell::StartsWith::None;
-}
-
-// 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)
-::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>>
-SwCursorShell::ExtendedSelectedAll() const
+bool SwCursorShell::ExtendedSelectedAll()
{
- if (m_pTableCursor)
- {
- return {};
- }
-
SwNodes& rNodes = GetDoc()->GetNodes();
- SwShellCursor const*const pShellCursor = getShellCursor(false);
- SwStartNode const* pStartNode(FindParentText(*pShellCursor));
-
- SwNodeIndex nNode(*pStartNode);
+ SwNodeIndex nNode = rNodes.GetEndOfAutotext();
SwContentNode* pStart = rNodes.GoNext(&nNode);
- if (!pStart)
- {
- return {};
- }
- nNode = *pStartNode->EndOfSectionNode();
+ nNode = rNodes.GetEndOfContent();
SwContentNode* pEnd = SwNodes::GoPrevious(&nNode);
- if (!pEnd)
- {
- return {};
- }
+
+ if (!pStart || !pEnd)
+ return false;
SwPosition aStart(*pStart, 0);
SwPosition aEnd(*pEnd, pEnd->Len());
- if (!(aStart == *pShellCursor->Start() && aEnd == *pShellCursor->End()))
- {
- return {};
- }
-
- auto const ends(::EndsWith(*pStartNode));
- if (::StartsWith(*pStartNode) == StartsWith::None
- && ends == StartsWith::None)
- {
- 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
- while (pStartNode->IsSectionNode()
- && pStartNode->GetIndex() == pStartNode->StartOfSectionNode()->GetIndex() + 1
- && pStartNode->EndOfSectionNode()->GetIndex() + 1 == pStartNode->StartOfSectionNode()->EndOfSectionNode()->GetIndex())
- {
- pStartNode = pStartNode->StartOfSectionNode();
- }
-
- // pStartNode is the node that fully contains the selection - the first
- // node of the selection is the first node inside pStartNode
- return ::std::make_pair(rNodes[pStartNode->GetIndex() + 1], tablesAtEnd);
+ SwShellCursor* pShellCursor = getShellCursor(false);
+ return aStart == *pShellCursor->Start() && aEnd == *pShellCursor->End();
}
typename SwCursorShell::StartsWith SwCursorShell::StartsWith_()
{
- SwShellCursor const*const pShellCursor = getShellCursor(false);
- // first, check if this is invalid; ExtendedSelectAll(true) may result in
- // a) an ordinary selection that is valid
- // b) a selection that is extended
- // c) a selection that is invalid and will cause FindParentText to loop
- SwNode const& rEndOfExtras(GetDoc()->GetNodes().GetEndOfExtras());
- if (pShellCursor->Start()->nNode.GetIndex() <= rEndOfExtras.GetIndex()
- && rEndOfExtras.GetIndex() < pShellCursor->End()->nNode.GetIndex())
+ SwNodes& rNodes = GetDoc()->GetNodes();
+ SwNodeIndex nNode(rNodes.GetEndOfExtras());
+ SwContentNode* pContentNode = rNodes.GoNext(&nNode);
+ if (pContentNode->FindTableNode())
{
- return StartsWith::None; // *very* extended, no ExtendedSelectedAll handling!
+ return StartsWith::Table;
}
- SwStartNode const*const pStartNode(FindParentText(*pShellCursor));
- if (auto const ret = ::StartsWith(*pStartNode); ret != StartsWith::None)
+ if (pContentNode->GetTextNode()->IsHidden())
{
- return ret;
+ return StartsWith::HiddenPara;
}
- if (auto const ret = ::EndsWith(*pStartNode); ret != StartsWith::None)
+ nNode = rNodes.GetEndOfContent();
+ pContentNode = SwNodes::GoPrevious(&nNode);
+ if (pContentNode->GetTextNode()->IsHidden())
{
- return ret;
+ return StartsWith::HiddenPara;
}
return StartsWith::None;
}
@@ -1751,8 +1483,8 @@ void SwCursorShell::VisPortChgd( const SwRect & rRect )
/** Set the cursor back into content.
- This should only be called if the cursor was moved (e.g. when deleting a
- text frame). The new position is calculated from its current position
+ This should only be called if the cursor was move somewhere else (e.g. when
+ deleting a border). The new position is calculated from its current position
in the layout.
*/
void SwCursorShell::UpdateCursorPos()
@@ -1764,7 +1496,7 @@ void SwCursorShell::UpdateCursorPos()
if (isInHiddenTextFrame(pShellCursor) && !ExtendedSelectedAll())
{
- SwCursorMoveState aTmpState(MV_SETONLYTEXT);
+ SwCursorMoveState aTmpState( MV_NONE );
aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
GetLayout()->GetCursorOfst( pShellCursor->GetPoint(), pShellCursor->GetPtPos(),
&aTmpState );
@@ -2553,7 +2285,7 @@ bool SwCursorShell::Pop(PopMode const eDelete,
if (PopMode::DeleteCurrent == eDelete)
{
- ::std::optional<SwCursorSaveState> oSaveState( *m_pCurrentCursor );
+ SwCursorSaveState aSaveState( *m_pCurrentCursor );
// If the visible SSelection was not changed
const Point& rPoint = pOldStack->GetPtPos();
@@ -2581,7 +2313,6 @@ bool SwCursorShell::Pop(PopMode const eDelete,
!m_pCurrentCursor->IsSelOvr( SwCursorSelOverFlags::Toggle |
SwCursorSelOverFlags::ChangePos ) )
{
- oSaveState.reset(); // prevent UAF
UpdateCursor(); // update current cursor
if (m_pTableCursor)
{ // tdf#106929 ensure m_pCurrentCursor ring is recreated from table
@@ -2663,8 +2394,6 @@ void SwCursorShell::ShowCursor()
{
if( !m_bBasicHideCursor )
{
- comphelper::FlagRestorationGuard g(mbSelectAll, StartsWith_() != StartsWith::None && ExtendedSelectedAll());
-
m_bSVCursorVis = true;
m_pCurrentCursor->SetShowTextInputFieldOverlay( true );
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index 379c0a7666be..b12fc72228e2 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -1933,166 +1933,6 @@ void SwDoc::DeleteCol( const SwCursor& rCursor )
GetIDocumentUndoRedo().EndUndo(SwUndoId::COL_DELETE, nullptr);
}
-void SwDoc::DelTable(SwTableNode *const pTableNd)
-{
- {
- // tdf#156267 remove DdeBookmarks before deleting nodes
- SwDataChanged aTmp(SwPaM(*pTableNd, *pTableNd->EndOfSectionNode()));
- }
-
- bool bNewTextNd = false;
- // Is it alone in a FlyFrame?
- SwNodeIndex aIdx( *pTableNd, -1 );
- const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
- if( pSttNd )
- {
- const sal_uLong nTableEnd = pTableNd->EndOfSectionIndex() + 1;
- const sal_uLong 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,
- getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
- }
-
- // Save the cursors (UNO and otherwise)
- SwPaM const* pSavePaM(nullptr);
- SwPaM forwardPaM{SwNodeIndex(*pTableNd->EndOfSectionNode())};
- if (forwardPaM.Move(fnMoveForward, GoInNode))
- {
- pSavePaM = &forwardPaM;
- }
- SwPaM backwardPaM{SwNodeIndex(*pTableNd)};
- if (backwardPaM.Move(fnMoveBackward, GoInNode))
- {
- if (pSavePaM == nullptr
- // try to stay in the same outer table cell
- || (forwardPaM.GetPoint()->nNode.GetNode().FindTableNode() != pTableNd->StartOfSectionNode()->FindTableNode()
- && forwardPaM.GetPoint()->nNode.GetNode().StartOfSectionIndex()
- < backwardPaM.GetPoint()->nNode.GetNode().StartOfSectionIndex()))
- {
- pSavePaM = &backwardPaM;
- }
- }
- assert(pSavePaM); // due to bNewTextNd this must succeed
- {
- SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
- ::PaMCorrAbs(tmpPaM, *pSavePaM->GetPoint());
- }
-
- // Move hard PageBreaks to the succeeding Node
- bool bSavePageBreak = false, bSavePageDesc = false;
- sal_uLong 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,
- getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
- }
-
- // Save the cursors (UNO and otherwise)
- SwPaM const* pSavePaM(nullptr);
- SwPaM forwardPaM{SwNodeIndex(*pTableNd->EndOfSectionNode())};
- if (forwardPaM.Move(fnMoveForward, GoInNode))
- {
- pSavePaM = &forwardPaM;
- }
- SwPaM backwardPaM{SwNodeIndex(*pTableNd)};
- if (backwardPaM.Move(fnMoveBackward, GoInNode))
- {
- if (pSavePaM == nullptr
- // try to stay in the same outer table cell
- || (forwardPaM.GetPoint()->nNode.GetNode().FindTableNode() != pTableNd->StartOfSectionNode()->FindTableNode()
- && forwardPaM.GetPoint()->nNode.GetNode().StartOfSectionIndex()
- < backwardPaM.GetPoint()->nNode.GetNode().StartOfSectionIndex()))
- {
- pSavePaM = &backwardPaM;
- }
- }
- assert(pSavePaM); // due to bNewTextNd this must succeed
- {
- SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
- ::PaMCorrAbs(tmpPaM, *pSavePaM->GetPoint());
- }
-
- // 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 );
- }
-
- GetDocShell()->GetFEShell()->UpdateTableStyleFormatting();
-
- getIDocumentState().SetModified();
- getIDocumentFieldsAccess().SetFieldsDirty( true, nullptr, 0 );
-}
-
bool SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn )
{
if( ::HasProtectedCells( rBoxes ))
@@ -2126,7 +1966,132 @@ bool SwDoc::DeleteRowCol( const SwSelBoxes& rBoxes, bool bColumn )
aSelBoxes[0]->GetSttIdx()-1 == nTmpIdx1 &&
nTmpIdx2 == pTableNd->EndOfSectionIndex() )
{
- DelTable(pTableNd);
+ bool bNewTextNd = false;
+ // Is it alone in a FlyFrame?
+ SwNodeIndex aIdx( *pTableNd, -1 );
+ const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
+ if( pSttNd )
+ {
+ const sal_uLong nTableEnd = pTableNd->EndOfSectionIndex() + 1;
+ const sal_uLong 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,
+ getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
+ }
+
+ // Save the cursors (UNO and otherwise)
+ SwPaM aSavePaM( SwNodeIndex( *pTableNd->EndOfSectionNode() ) );
+ if( ! aSavePaM.Move( fnMoveForward, GoInNode ) )
+ {
+ *aSavePaM.GetMark() = SwPosition( *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;
+ sal_uLong 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,
+ getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_STANDARD ) );
+ }
+
+ // Save the cursors (UNO and otherwise)
+ SwPaM aSavePaM( SwNodeIndex( *pTableNd->EndOfSectionNode() ) );
+ if( ! aSavePaM.Move( fnMoveForward, GoInNode ) )
+ {
+ *aSavePaM.GetMark() = SwPosition( *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 );
+ }
+
+ GetDocShell()->GetFEShell()->UpdateTableStyleFormatting();
+
+ getIDocumentState().SetModified();
+ getIDocumentFieldsAccess().SetFieldsDirty( true, nullptr, 0 );
+
return true;
}
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index e16b8256b611..aa56a85ae43f 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -42,9 +42,7 @@
void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool *const pUndo)
{
- auto const oSelectAll(StartsWith_() != SwCursorShell::StartsWith::None
- ? ExtendedSelectedAll()
- : ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode *>>>{});
+ bool bSelectAll = StartsWith_() != SwCursorShell::StartsWith::None && ExtendedSelectedAll();
// only for selections
if (!rPam.HasMark()
|| (*rPam.GetPoint() == *rPam.GetMark()
@@ -60,7 +58,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.GetNode().FindTableNode() &&
rPam.GetNode().StartOfSectionNode() !=
- rPam.GetNode(false).StartOfSectionNode() && !oSelectAll)
+ rPam.GetNode(false).StartOfSectionNode() && !bSelectAll )
{
// group the Undo in the table
if( pUndo && !*pUndo )
@@ -104,34 +102,30 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, bool
{
std::unique_ptr<SwPaM> pNewPam;
SwPaM * pPam = &rPam;
- if (oSelectAll)
+ if (bSelectAll)
{
- 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)
- {
- GetDoc()->DelTable(pTable);
- }
assert(dynamic_cast<SwShellCursor*>(&rPam)); // must be corrected pam
pNewPam.reset(new SwPaM(*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() = SwPosition(*oSelectAll->first);
+ while (SwTableNode const* pTableNode =
+ pNewPam->Start()->nNode.GetNode().StartOfSectionNode()->FindTableNode())
+ {
+ pNewPam->Start()->nNode = *pTableNode;
+ }
+ // tdf#133990 ensure section is included in SwUndoDelete
+ while (SwSectionNode const* pSectionNode =
+ pNewPam->Start()->nNode.GetNode().StartOfSectionNode()->FindSectionNode())
+ {
+ pNewPam->Start()->nNode = *pSectionNode;
+ }
+ pNewPam->Start()->nContent.Assign(nullptr, 0);
pPam = pNewPam.get();
}
// delete everything
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
diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx
index bad2bb719a86..0d27b7c7a960 100644
--- a/sw/source/core/edit/edglss.cxx
+++ b/sw/source/core/edit/edglss.cxx
@@ -203,9 +203,7 @@ bool SwEditShell::CopySelToDoc( SwDoc* pInsDoc )
bool bColSel = GetCursor_()->IsColumnSelection();
if( bColSel && pInsDoc->IsClipBoard() )
pInsDoc->SetColumnSelection( true );
- auto const oSelectAll(StartsWith_() != SwCursorShell::StartsWith::None
- ? ExtendedSelectedAll()
- : ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>>{});
+ bool bSelectAll = StartsWith_() != SwCursorShell::StartsWith::None && ExtendedSelectedAll();
{
for(SwPaM& rPaM : GetCursor()->GetRingContainer())
{
@@ -229,12 +227,18 @@ bool SwEditShell::CopySelToDoc( SwDoc* pInsDoc )
// 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 (oSelectAll)
+ if (bSelectAll)
{
// 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() = SwPosition(*oSelectAll->first);
+ // tdf#133982 tables can be nested
+ while (SwTableNode const* pTableNode =
+ aPaM.Start()->nNode.GetNode().StartOfSectionNode()->FindTableNode())
+ {
+ aPaM.Start()->nNode = *pTableNode;
+ }
+ aPaM.Start()->nContent.Assign(nullptr, 0);
}
bRet = GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, /*bCopyAll=*/false, /*bCheckPos=*/true, /*bCopyText=*/false ) || bRet;
}
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 8ff858013b72..336e447a94c6 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -798,26 +798,30 @@ void SwUndoSaveContent::MoveFromUndoNds( SwDoc& rDoc, sal_uLong nNodeIdx,
}
}
-// These two methods save and restore the Point of PaM.
-// If the point cannot be moved, a "backup" is created on the previous node.
-// Either way, returned, inserting at its original position will not move it.
-::std::optional<SwNodeIndex> SwUndoSaveContent::MovePtBackward(SwPaM & rPam)
+// These two methods move the Point of Pam backwards/forwards. With that, one
+// can span an area for a Undo/Redo. (The Point is then positioned in front of
+// the area to manipulate!)
+// The flag indicates if there is still content in front of Point.
+bool SwUndoSaveContent::MovePtBackward( SwPaM& rPam )
{
rPam.SetMark();
if( rPam.Move( fnMoveBackward ))
- return {};
+ return true;
- return { SwNodeIndex(rPam.GetPoint()->nNode, -1) };
+ // If there is no content onwards, set Point simply to the previous position
+ // (Node and Content, so that Content will be detached!)
+ --rPam.GetPoint()->nNode;
+ rPam.GetPoint()->nContent.Assign( nullptr, 0 );
+ return false;
}
-void SwUndoSaveContent::MovePtForward(SwPaM& rPam, ::std::optional<SwNodeIndex> && oMvBkwrd)
+void SwUndoSaveContent::MovePtForward( SwPaM& rPam, bool bMvBkwrd )
{
// Was there content before this position?
- if (!oMvBkwrd)
+ if( bMvBkwrd )
rPam.Move( fnMoveForward );
else
{
- *rPam.GetPoint() = SwPosition(*oMvBkwrd);
++rPam.GetPoint()->nNode;
SwContentNode* pCNd = rPam.GetContentNode();
if( pCNd )
diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx
index ff3f4777329c..f1f7f48188aa 100644
--- a/sw/source/core/undo/unins.cxx
+++ b/sw/source/core/undo/unins.cxx
@@ -328,7 +328,7 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext)
if( nLen )
{
- ::std::optional<SwNodeIndex> oMvBkwrd = MovePtBackward(*pPam);
+ const bool bMvBkwrd = MovePtBackward( *pPam );
if (maText)
{
@@ -355,7 +355,7 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext)
nNode = pPam->GetMark()->nNode.GetIndex();
nContent = pPam->GetMark()->nContent.GetIndex();
- MovePtForward(*pPam, ::std::move(oMvBkwrd));
+ MovePtForward( *pPam, bMvBkwrd );
pPam->Exchange();
if( pRedlData && IDocumentRedlineAccess::IsRedlineOn( GetRedlineFlags() ))
{
diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx
index 01561018ec56..449f41795697 100644
--- a/sw/source/core/undo/untblk.cxx
+++ b/sw/source/core/undo/untblk.cxx
@@ -357,15 +357,15 @@ void SwUndoInserts::RedoImpl(::sw::UndoRedoContext & rContext)
auto const pFlysAtInsPos(sw::GetFlysAnchoredAt(*pDoc,
rPam.GetPoint()->nNode.GetIndex()));
- ::std::optional<SwNodeIndex> oMvBkwrd = MovePtBackward(rPam);
+ const bool bMvBkwrd = MovePtBackward(rPam);
// re-insert content again (first detach m_pUndoNodeIndex!)
sal_uLong const nMvNd = m_pUndoNodeIndex->GetIndex();
m_pUndoNodeIndex.reset();
MoveFromUndoNds(*pDoc, nMvNd, *rPam.GetMark());
- if (m_nDeleteTextNodes != 0 || oMvBkwrd)
+ if (m_nDeleteTextNodes != 0)
{
- MovePtForward(rPam, ::std::move(oMvBkwrd));
+ MovePtForward(rPam, bMvBkwrd);
}
rPam.Exchange();
diff --git a/sw/source/uibase/wrtsh/move.cxx b/sw/source/uibase/wrtsh/move.cxx
index b0dcdc522de7..76f4baedaba5 100644
--- a/sw/source/uibase/wrtsh/move.cxx
+++ b/sw/source/uibase/wrtsh/move.cxx
@@ -218,25 +218,12 @@ bool SwWrtShell::GoStart( bool bKeepArea, bool *pMoveTable,
*pMoveTable = false;
return true;
}
- SwTableNode const*const pTable(getShellCursor(false)->GetPoint()->nNode.GetNode().FindTableNode());
- assert(pTable);
if( MoveTable( GotoCurrTable, fnTableStart ) || bDontMoveRegion )
{
if ( pMoveTable )
*pMoveTable = true;
return true;
}
- else if (SwCursor const*const pCursor = getShellCursor(false);
- pTable->GetNodes()[pTable->GetIndex()+1]->EndOfSectionIndex()
- < pCursor->GetPoint()->nNode.GetNode().GetIndex()
- && pMoveTable != nullptr // only set by SelAll()
- // problem: cursor isn't inside 1st cell, and didn't move there
- // workaround: try to move cursor outside of table for SelAll()
- && MoveOutOfTable())
- {
- assert(!*pMoveTable);
- return true;
- }
else if( bBoxSelection && pMoveTable )
{
// JP 09.01.96: We have a box selection (or an empty cell)
@@ -271,40 +258,15 @@ bool SwWrtShell::GoStart( bool bKeepArea, bool *pMoveTable,
else if ( bKeepArea )
return true;
}
-
- // first try to move to the start of the current SwSection
+ // Regions ???
return SwCursorShell::MoveRegion( GotoCurrRegionAndSkip, fnRegionStart ) ||
- (pMoveTable != nullptr
- // move to start of text - if in different table, move out
- ? MoveStartText()
- // TODO who needs SttEndDoc for other case?
- : SwCursorShell::SttEndDoc(true));
+ SwCursorShell::SttEndDoc(true);
}
bool SwWrtShell::GoEnd(bool bKeepArea, const bool *pMoveTable)
{
- if (pMoveTable && *pMoveTable) // only in SelAll()
- {
- SwTableNode const*const pTable(getShellCursor(false)->GetPoint()->nNode.GetNode().FindTableNode());
- assert(pTable);
- if (MoveTable(GotoCurrTable, fnTableEnd))
- {
- return true;
- }
- else if (SwCursor const*const pCursor = getShellCursor(false);
- pCursor->GetPoint()->nNode.GetNode().GetIndex()
- < pTable->GetNodes()[pTable->EndOfSectionIndex()-1]->StartOfSectionIndex()
- // problem: cursor isn't inside 1st cell, and didn't move there
- // workaround: try to move cursor outside of table for SelAll()
- && MoveOutOfTable())
- {
- return true;
- }
- else
- {
- return false;
- }
- }
+ if ( pMoveTable && *pMoveTable )
+ return MoveTable( GotoCurrTable, fnTableEnd );
if ( IsCursorInTable() )
{
diff --git a/sw/source/uibase/wrtsh/select.cxx b/sw/source/uibase/wrtsh/select.cxx
index 17d4c068416a..f26bb97bc8f4 100644
--- a/sw/source/uibase/wrtsh/select.cxx
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -141,10 +141,7 @@ void SwWrtShell::SelAll()
bool bHasWholeTabSelection = HasWholeTabSelection();
bool bIsCursorInTable = IsCursorInTable();
- if (!bHasWholeTabSelection
- && ( !bIsCursorInTable
- || getShellCursor(false)->GetNode(false).FindTableNode() == nullptr
- || !ExtendedSelectedAll())) // ESA inside table -> else branch
+ if (!bHasWholeTabSelection)
{
if ( IsSelection() && IsCursorPtAtEnd() )
SwapPam();
@@ -160,35 +157,30 @@ void SwWrtShell::SelAll()
bIsFullSel &= !MoveSection( GoCurrSection, fnSectionEnd);
Pop(SwCursorShell::PopMode::DeleteCurrent);
GoStart(true, &bMoveTable, false, !bIsFullSel);
- SttSelect();
- GoEnd(true, &bMoveTable);
}
else
{
- if (MoveOutOfTable())
- { // select outer text
- EnterStdMode(); // delete m_pTableCursor
-// GoStart(true, &bMoveTable, false, true);
- MoveSection(GoCurrSection, fnSectionStart); // don't move into prev table
- SttSelect();
- MoveSection(GoCurrSection, fnSectionEnd); // don't move to different cell
- }
- else
- {
- TrySelectOuterTable();
- }
+ EnterStdMode();
+ SttEndDoc(true);
}
+ SttSelect();
+ GoEnd(true, &bMoveTable);
bool bNeedsExtendedSelectAll = StartsWith_() != StartsWith::None;
- // the GoEnd() could have created a table selection, if so avoid ESA.
+ // If the cursor was in a table, then we only need the extended select
+ // all if the whole table is already selected, to still allow selecting
+ // only a single cell or a single table before selecting the whole
+ // document.
if (bNeedsExtendedSelectAll && bIsCursorInTable)
- {
- bNeedsExtendedSelectAll = !HasWholeTabSelection();
- }
+ bNeedsExtendedSelectAll = bHasWholeTabSelection;
if (bNeedsExtendedSelectAll)
{
+ // Disable table cursor to make sure getShellCursor() returns m_pCurrentCursor, not m_pTableCursor.
+ if (IsTableMode())
+ TableCursorToCursor();
+ // Do the extended select all on m_pCurrentCursor.
ExtendedSelectAll(/*bFootnotes =*/ false);
}