diff options
author | Michael Stahl <michael.stahl@allotropia.de> | 2024-02-26 13:58:18 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@allotropia.de> | 2024-02-26 14:58:47 +0100 |
commit | 6eb71b1778d8bc44ec642f3e61096350e4c868dc (patch) | |
tree | ecf973d0d644ec8af66de3978e7a91fa2d123171 | |
parent | 678b716506c20566167d19168f33aa94db7407e3 (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.hxx | 14 | ||||
-rw-r--r-- | sw/inc/doc.hxx | 1 | ||||
-rw-r--r-- | sw/inc/undobj.hxx | 12 | ||||
-rw-r--r-- | sw/qa/extras/odfimport/odfimport.cxx | 4 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt | 219 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 22 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 18 | ||||
-rw-r--r-- | sw/source/core/crsr/crsrsh.cxx | 321 | ||||
-rw-r--r-- | sw/source/core/docnode/ndtbl.cxx | 287 | ||||
-rw-r--r-- | sw/source/core/edit/eddel.cxx | 36 | ||||
-rw-r--r-- | sw/source/core/edit/edglss.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/undo/undobj.cxx | 22 | ||||
-rw-r--r-- | sw/source/core/undo/unins.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/undo/untblk.cxx | 6 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/move.cxx | 46 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/select.cxx | 36 |
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); } |