diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/undobj.hxx | 6 | ||||
-rw-r--r-- | sw/qa/core/uwriter.cxx | 3 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odt | bin | 0 -> 9251 bytes | |||
-rw-r--r-- | sw/qa/extras/uiwriter/data/redline_fly_duplication_at_para_2nd_paragraph.fodt | 222 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 16 | ||||
-rw-r--r-- | sw/qa/uitest/writer_tests4/tdf108124.py | 15 | ||||
-rw-r--r-- | sw/source/core/access/accframebase.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/access/accmap.cxx | 18 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentContentOperationsManager.cxx | 45 | ||||
-rw-r--r-- | sw/source/core/doc/docedt.cxx | 57 | ||||
-rw-r--r-- | sw/source/core/edit/edglbldc.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/layout/trvlfrm.cxx | 17 | ||||
-rw-r--r-- | sw/source/core/undo/undobj.cxx | 96 | ||||
-rw-r--r-- | sw/source/core/undo/untblk.cxx | 17 |
14 files changed, 374 insertions, 143 deletions
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx index dc271d0cf94d..cde1e3a0ff35 100644 --- a/sw/inc/undobj.hxx +++ b/sw/inc/undobj.hxx @@ -135,7 +135,7 @@ enum class DelContentType : sal_uInt16 Fly = 0x02, Bkm = 0x08, AllMask = 0x0b, - ExcludeAtCharFlyAtStartEnd = 0x40, + ExcludeFlyAtStartEnd = 0x40, CheckNoCntnt = 0x80, }; namespace o3tl { @@ -146,6 +146,10 @@ namespace o3tl { bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos, SwPosition const & rStart, SwPosition const & rEnd, DelContentType const nDelContentType = DelContentType::AllMask); +/// is a fly anchored at paragraph at rAnchorPos selected? +bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos, + SwPosition const & rStart, SwPosition const & rEnd, + DelContentType const nDelContentType = DelContentType::AllMask); // This class has to be inherited into an Undo-object if it saves content // for Redo/Undo... diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx index 575baa3c32ee..22cd289c7f27 100644 --- a/sw/qa/core/uwriter.cxx +++ b/sw/qa/core/uwriter.cxx @@ -1165,8 +1165,7 @@ void SwDocTest::randomTest() SwMoveFlags nFlags = getRand(1) // FIXME: puterb this more ? ? SwMoveFlags::DEFAULT - : SwMoveFlags::ALLFLYS | - SwMoveFlags::CREATEUNDOOBJ | + : SwMoveFlags::CREATEUNDOOBJ | SwMoveFlags::REDLINES | SwMoveFlags::NO_DELFRMS; SwPosition aTo(getRandomPosition(m_pDoc, i/10)); diff --git a/sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odt b/sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odt Binary files differnew file mode 100644 index 000000000000..a4b41e4ec25d --- /dev/null +++ b/sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odt diff --git a/sw/qa/extras/uiwriter/data/redline_fly_duplication_at_para_2nd_paragraph.fodt b/sw/qa/extras/uiwriter/data/redline_fly_duplication_at_para_2nd_paragraph.fodt new file mode 100644 index 000000000000..230159513ba0 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/redline_fly_duplication_at_para_2nd_paragraph.fodt @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle: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:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:font-face-decls> + <style:font-face style:name="Wingdings" svg:font-family="Wingdings" style:font-pitch="variable" style:font-charset="x-symbol"/> + <style:font-face style:name="Symbol" svg:font-family="Symbol" style:font-family-generic="roman" style:font-pitch="variable" style:font-charset="x-symbol"/> + <style:font-face style:name="Arial" svg:font-family="Arial"/> + <style:font-face style:name="Scala-Regular" svg:font-family="Scala-Regular"/> + <style:font-face style:name="ScalaPro-Regular" svg:font-family="ScalaPro-Regular"/> + <style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/> + <style:font-face style:name="Courier New" svg:font-family="'Courier New'" style:font-family-generic="modern"/> + <style:font-face style:name="ScalaPro-Bold" svg:font-family="ScalaPro-Bold" style:font-family-generic="roman"/> + <style:font-face style:name="Arial4" svg:font-family="Arial, Arial" style:font-family-generic="swiss"/> + <style:font-face style:name="Arial1" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="Arial2" svg:font-family="Arial" style:font-adornments="Fett" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="Arial3" svg:font-family="Arial" style:font-adornments="Standard" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="Arial Unicode MS" svg:font-family="'Arial Unicode MS'" style:font-family-generic="swiss" style:font-pitch="variable"/> + <style:font-face style:name="DejaVu Sans" svg:font-family="'DejaVu Sans'" 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="#000000" draw:fill-color="#99ccff" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/> + <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false"> + <style:tab-stops/> + </style:paragraph-properties> + <style:text-properties style:use-window-font-color="true" style:font-name="Arial" fo:font-size="11pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="DejaVu Sans" style:font-size-asian="12pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="DejaVu Sans" 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: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" style:font-name="Arial" fo:font-size="11pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="DejaVu Sans" style:font-size-asian="12pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="DejaVu Sans" 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"/> + </style:default-style> + <style:default-style style:family="table"> + <style:table-properties table:border-model="collapsing"/> + </style:default-style> + <style:default-style style:family="table-row"> + <style:table-row-properties fo:keep-together="auto"/> + </style:default-style> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text"> + <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.212cm" loext:contextual-spacing="false"/> + </style:style> + <style:style style:name="RGUgliederung" style:family="paragraph" style:parent-style-name="Standard" style:list-style-name="WW8Num6"> + <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0.529cm" loext:contextual-spacing="false" style:line-height-at-least="0.529cm" fo:text-indent="0cm" style:auto-text-indent="false" style:text-autospace="none" style:punctuation-wrap="simple" style:vertical-align="baseline"> + <style:tab-stops> + <style:tab-stop style:position="0.751cm"/> + <style:tab-stop style:position="16.277cm"/> + </style:tab-stops> + </style:paragraph-properties> + <style:text-properties style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="Bullet_20_Symbols" style:display-name="Bullet Symbols" style:family="text"> + <style:text-properties style:font-name="StarSymbol" fo:font-family="StarSymbol" fo:font-size="9pt" style:font-name-asian="StarSymbol" style:font-family-asian="StarSymbol" style:font-size-asian="9pt" style:font-name-complex="StarSymbol" style:font-family-complex="StarSymbol" style:font-size-complex="9pt"/> + </style:style> + <style:style style:name="WW8Num6z1" style:family="text"> + <style:text-properties style:font-name="Courier New" fo:font-family="'Courier New'" style:font-family-generic="modern"/> + </style:style> + <style:style style:name="WW8Num6z0" style:family="text"> + <style:text-properties style:font-name="Wingdings" fo:font-family="Wingdings" style:font-pitch="variable" style:font-charset="x-symbol"/> + </style:style> + <style:style style:name="WW8Num6z3" style:family="text"> + <style:text-properties style:font-name="Symbol" fo:font-family="Symbol" style:font-family-generic="roman" style:font-pitch="variable" style:font-charset="x-symbol"/> + </style:style> + <style:style style:name="Graphics" style:family="graphic"> + <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" style:wrap="none" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph"/> + </style:style> + <text:list-style style:name="WW8Num6" text:consecutive-numbering="true"> + <text:list-level-style-bullet text:level="1" text:style-name="Bullet_20_Symbols" text:bullet-char="•"> + <style:list-level-properties text:space-before="0.635cm" text:min-label-width="0.635cm"/> + <style:text-properties fo:font-family="StarSymbol" style:font-charset="x-symbol"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="2" text:style-name="WW8Num6z1" text:bullet-char="o"> + <style:list-level-properties text:space-before="1.905cm" text:min-label-width="0.635cm"/> + <style:text-properties fo:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="3" text:style-name="WW8Num6z0" text:bullet-char=""> + <style:list-level-properties text:space-before="3.175cm" text:min-label-width="0.635cm"/> + <style:text-properties style:font-name="Wingdings"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="4" text:style-name="WW8Num6z3" text:bullet-char=""> + <style:list-level-properties text:space-before="4.445cm" text:min-label-width="0.635cm"/> + <style:text-properties style:font-name="Symbol"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="5" text:style-name="WW8Num6z1" text:bullet-char="o"> + <style:list-level-properties text:space-before="5.715cm" text:min-label-width="0.635cm"/> + <style:text-properties fo:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="6" text:style-name="WW8Num6z0" text:bullet-char=""> + <style:list-level-properties text:space-before="6.985cm" text:min-label-width="0.635cm"/> + <style:text-properties style:font-name="Wingdings"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="7" text:style-name="WW8Num6z3" text:bullet-char=""> + <style:list-level-properties text:space-before="8.255cm" text:min-label-width="0.635cm"/> + <style:text-properties style:font-name="Symbol"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="8" text:style-name="WW8Num6z1" text:bullet-char="o"> + <style:list-level-properties text:space-before="9.525cm" text:min-label-width="0.635cm"/> + <style:text-properties fo:font-family="'Courier New'" style:font-family-generic="modern" style:font-pitch="fixed"/> + </text:list-level-style-bullet> + <text:list-level-style-bullet text:level="9" text:style-name="WW8Num6z0" text:bullet-char=""> + <style:list-level-properties text:space-before="10.795cm" text:min-label-width="0.635cm"/> + <style:text-properties style:font-name="Wingdings"/> + </text:list-level-style-bullet> + <text:list-level-style-number text:level="10" style:num-suffix="." style:num-format="1"> + <style:list-level-properties text:space-before="6.35cm" text:min-label-width="0.635cm"/> + </text:list-level-style-number> + </text:list-style> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="RGUgliederung" style:list-style-name="WW8Num6"> + <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.229cm" loext:contextual-spacing="false"/> + <style:text-properties fo:color="#000000"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="RGUgliederung" style:list-style-name=""> + <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.229cm" loext:contextual-spacing="false"/> + <style:text-properties fo:color="#000000"/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="RGUgliederung" style:list-style-name=""> + <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"/> + <style:text-properties fo:color="#000000" style:font-name="Arial1" fo:font-size="11pt" fo:font-weight="normal" officeooo:rsid="0036e634" officeooo:paragraph-rsid="002d5bb4" style:font-name-asian="Scala-Regular" style:font-size-asian="11pt" style:font-weight-asian="normal" style:font-name-complex="Scala-Regular" style:font-size-complex="11pt" style:font-weight-complex="normal"/> + </style:style> + <style:style style:name="P5" style:family="paragraph" style:parent-style-name="RGUgliederung" style:list-style-name=""> + <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false"/> + <style:text-properties fo:color="#000000" style:font-name="Arial2" fo:font-size="11pt" fo:font-weight="normal" officeooo:rsid="0036e634" officeooo:paragraph-rsid="002d5bb4" style:font-name-asian="Scala-Regular" style:font-size-asian="11pt" style:font-weight-asian="normal" style:font-name-complex="Scala-Regular" style:font-size-complex="11pt" style:font-weight-complex="normal"/> + </style:style> + <style:style style:name="P6" style:family="paragraph" style:parent-style-name="RGUgliederung" style:list-style-name=""> + <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.229cm" loext:contextual-spacing="false"/> + <style:text-properties fo:color="#000000"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:text-properties fo:color="#231f20" style:font-name="Arial3" fo:font-size="10pt" fo:font-style="normal" fo:font-weight="normal" style:font-name-asian="ScalaPro-Regular" style:font-size-asian="10pt" style:font-name-complex="ScalaPro-Regular" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="T2" style:family="text"> + <style:text-properties fo:color="#231f20" style:font-name="Arial3" fo:font-size="10pt" fo:font-style="normal" fo:font-weight="normal" style:font-name-asian="ScalaPro-Bold" style:font-size-asian="10pt" style:font-name-complex="ScalaPro-Bold" style:font-size-complex="10pt"/> + </style:style> + <style:style style:name="T3" style:family="text"> + <style:text-properties style:font-name="Arial1" fo:font-size="11pt" style:text-underline-style="none" fo:font-weight="bold" style:font-name-asian="ScalaPro-Regular" style:font-size-asian="11pt" style:font-weight-asian="bold" style:font-name-complex="ScalaPro-Regular" style:font-size-complex="11pt" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="T4" style:family="text"> + <style:text-properties style:font-name="Arial1" fo:font-size="11pt" style:text-underline-style="none" fo:font-weight="bold" style:font-name-asian="Arial4" style:font-size-asian="11pt" style:font-weight-asian="bold" style:font-name-complex="Arial1" style:font-size-complex="11pt" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="T5" style:family="text"> + <style:text-properties style:font-name="Arial2" style:font-name-asian="ScalaPro-Regular" style:font-name-complex="ScalaPro-Regular"/> + </style:style> + <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics"> + <style:graphic-properties style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/> + </style:style> + <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:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="none" 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:tracked-changes> + <text:changed-region xml:id="ct121341168" text:id="ct121341168"> + <text:deletion> + <office:change-info> + <dc:creator>Unknown Author</dc:creator> + <dc:date>2019-12-04T18:05:04</dc:date> + </office:change-info> + <text:p text:style-name="P1">x</text:p> + <text:p text:style-name="P1"><draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="paragraph" svg:width="0.67cm" svg:height="0.67cm" draw:z-index="0"><draw:image loext:mime-type="image/png"> + <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAHoAAAAlCAYAAACNgf3GAAAACXBIWXMAAA66AAAOoQG8if1I + AAAG5klEQVR4nO1bbUwURxguFkqDZ7iKkIK0IiHBYjVcUzwRkQiFShPaBk21NhICP2wLBUlo + +PComMJRBU6OAyR3FUgjFmnAClEIBpXwlYoGQ0NV1BqhBAuRgtUaUKDz/LiErHt7H7PHbdZ7 + EkLYOebdvWfemfd5ZtZxYWHhFTvED0db34AdSwM70VbAwMBA2MjIiL+t4q9du/b3gICA3sXX + 7ETzjOvXr4dnZWW1PH/+/DVbxF+9evUdtVq9hXnd6kSTGsCB/CwjmLN2LFvj3r17G3Jzcxtt + RbKrq+uEUqmMxm9mm1WJHhsb89VqtYU5OTmfWTOOEDAxMeF98ODB80+ePHG1RXxnZ+f/8vLy + Yry8vO6wtVuFaGTwmTNnUqqrq/M2bdp0XuzZDHJBMsi2RXx8vyT+5+vWrfvN0Gd4J3p4ePid + oqKiqhs3bmzG33K5/BzfMYQETNOHDx9uxLRtq3vYv39/enBwcBPXZ3gjem5uzrGuri6ztrZW + 8ezZM2dcc3BwWCAZ3cJXDKEB9QcGdX9/fzhbe0RERG1ycvI3tHGqqqrym5ubv2Jri4mJOR4b + G1tirA9eiL59+/Z7xcXFJ+7evRu4+Lqfn1+/VCod5yOGEEEIULa3t3/B1iaTyS6mp6cnODo6 + ztLEuHDhQpwhkpHFpg4kKqJnZ2dfP3ny5Hf19fXfIqOZ7WKetvHlYwZja4OOPXToUCwtyZBq + KpVKx9aG9Rjrsqn1j8VEDw4OhiCLuYwBFGKW9i9k9Pb2flxWVqZha3N3d/8rPz//o+XLl0/T + xOCSatDKqLBRaZvan9lEP336VIIpq6mpKWl+fn6Zoc+tWLFi0t/fv8/c/oWOmzdvygmRP5Nn + f5XZBnJBMsimicEl1bi0MhfMIvratWuRJSUl2gcPHvgY+2xQUFCr2GQVFIVCoWiemZlxYbZh + miYZGItpmyYGl1QzppW5YBLRjx8/llZWVqra2triUWma8j9iW5/xxWdmZrZNT0+7M9swoEnb + vsDAwIs0MbikmilamQtGie7u7v5Uo9GUP3z40Mucjnt6ej6BuW/JTQkReBZDhggq37CwsHqa + /o1JNcQwppW5YJDoqakpj/Ly8tLLly/vtqTjjo4O0duewJ49e36AlqXth0uq8RGDlWgErKio + UD969MiNpnOxA4ZIQkJCNm0/XFKNrxgvEI11uLCwsJq2Y7FDIpFMpaamfgn3j6af+/fvBxiS + apBRMF1oYwAvEB0VFVUjlUr/VqvVlePj42/TBhArUKDiO8rIyNhHQ8SaNWv+wLR89uzZZGbb + 6OioX0tLSyIfSwPr1A1/WqfTvUvWjQJMK1x6+WUGljiimUcSExOzaPpJSkpKIQPnDbY1Gtm+ + atWqUZpCDDBYjLm4uPxLKr3k7du3n1KpVD9CQ5rTMR4epgnNzQkJyDg22YO11cPDY5gm6zAj + YIqenJz0ZFbdMGZg0Bw5ciRq/fr13ZbGMCqvSOc9REPLsCt1+vTpDKL1nEzpGA8fHh5+ytIb + Expg55I1uZdNYiHrsHkTGhraYGn/MFzgj6elpXUyBxQMGqKhzx07dizUUkPGJMPEyclpJj4+ + Pmfbtm2/wN8eGhp639j/9PX17RAT0bA1jx49GnHgwIEupmmCrFMqlacKCgqiaUwTvYXKNqD0 + jhmpC4ItsVjNskB9fX0HNBrN5sbGxtSamprv2axAPa5evfohTpqQaWne3JsSKry9vYdgQZJp + 9iLz2eFqYROCJusAkEgGzQ4S4xJzQOk9cMQwd9PE7E0NWHG7du1ShYSE/EoC6gw5OTBcbt26 + FWSpZSdU6LcHQSpzY4M26/Tw8fEZNDSgMK3DJsXGhjnboBZvU3p6ev5JCoQPWltbE7RabRHk + BvMzV65ciRYb0YB+w7+0tLSC2UaTdYvBNaCQXFgqFArFbqvvRwOoFqOjo0/I5fLzZEov6+rq + il3cjnU6Li4ulyaGUIEqGz4Dm6NladYxwTWgOjs7d6IITElJ+dqUvng5SrRy5coxUjHuBNHY + ACEy4U1cJ0VbEKZwsR4ngjVJMvgtNv2LrMMmBe2ZMSJv6zBw2I4T4RrUDbxwY/3wegp069at + jaTqvETkWDGsVBgtyOrIyMif+IwjFHDpXwADwNBGBV/AZghMG3jiXJ/j/bivRCL5Bw+PwGSd + 0qL6FivRAJf+XQrotzfd3NzGuKSd1d7UkMlk7TqdbkNDQ0MaboYPY16o4NK/SwFIO5x8IYSH + Gyp+rfpKDo6+7N27N9+aMYQC/aFAZLYtXsuBDAPZpHDbwnbUyP42JY+AUYJzY7Z6mxIGS3Z2 + dgvepmQeHrQTzTOwTmIDwpbvR2N70070EmDjxo0d+LH1fSyGneiXBP8DiC6/s246dP8AAAAA + SUVORK5CYII= + </office:binary-data> + </draw:image></draw:frame>x</text:p> + <text:p text:style-name="P1"/> + </text:deletion> + </text:changed-region> + </text:tracked-changes> + <text:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:p text:style-name="P1">x<text:change text:change-id="ct121341168"/></text:p> + <text:p text:style-name="P1"></text:p> + </office:text> + </office:body> +</office:document> + diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 1ede61bc5bad..f4ceaeb25839 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -168,6 +168,8 @@ public: void testRedlineFrameAtCharStartInside(); void testRedlineFrameAtParaStartOutside(); void testRedlineFrameAtParaEndInside(); + void testRedlineFrameAtParaOneParagraph(); + void testRedlineFrameAtPara2ndParagraph(); void testThreadedException(); void testBookmarkCopy(); void testFdo69893(); @@ -368,6 +370,8 @@ public: CPPUNIT_TEST(testRedlineFrameAtCharStartInside); CPPUNIT_TEST(testRedlineFrameAtParaStartOutside); CPPUNIT_TEST(testRedlineFrameAtParaEndInside); + CPPUNIT_TEST(testRedlineFrameAtParaOneParagraph); + CPPUNIT_TEST(testRedlineFrameAtPara2ndParagraph); CPPUNIT_TEST(testThreadedException); CPPUNIT_TEST(testBookmarkCopy); CPPUNIT_TEST(testFdo69893); @@ -684,6 +688,18 @@ void SwUiWriterTest::testRedlineFrameAtParaEndInside() testRedlineFrame("redline_fly_duplication_at_para_end_inside.fodt"); } +void SwUiWriterTest::testRedlineFrameAtParaOneParagraph() +{ + // test ALLFLYS flag: oddly enough it didn't fail as fodt but failed as odt... + testRedlineFrame("redline_fly_at_para_one_paragraph.odt"); +} + +void SwUiWriterTest::testRedlineFrameAtPara2ndParagraph() +{ + // lost via the buggy increment in Copy + testRedlineFrame("redline_fly_duplication_at_para_2nd_paragraph.fodt"); +} + void SwUiWriterTest::testThreadedException() { SvFileStream aFileStream(m_directories.getURLFromSrc(DATA_DIRECTORY) + "threadedException.fodt", StreamMode::READ); diff --git a/sw/qa/uitest/writer_tests4/tdf108124.py b/sw/qa/uitest/writer_tests4/tdf108124.py index 168f51bff33a..929a3d7b498d 100644 --- a/sw/qa/uitest/writer_tests4/tdf108124.py +++ b/sw/qa/uitest/writer_tests4/tdf108124.py @@ -28,11 +28,22 @@ class tdf108124(UITestCase): xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+a"})) # select all xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+c"})) # copy xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+v"})) # paste - self.assertEqual(document.GraphicObjects.getCount(), 4) + self.assertEqual(document.GraphicObjects.getCount(), 2) + xObj1Old = document.GraphicObjects[0] + xObj2Old = document.GraphicObjects[1] self.xUITest.executeCommand(".uno:Undo") #Undo self.assertEqual(document.GraphicObjects.getCount(), 2) + xObj1New = document.GraphicObjects[0] + xObj2New = document.GraphicObjects[1] + # there should be 2 different objects now but they have the same names, + # so rely on the object identity for testing... + self.assertNotEqual(xObj1Old, xObj1New) + self.assertNotEqual(xObj1Old, xObj2New) + self.assertNotEqual(xObj2Old, xObj1New) + self.assertNotEqual(xObj2Old, xObj2New) self.xUITest.executeCommand(".uno:Redo") #Redo - self.assertEqual(document.GraphicObjects.getCount(), 4) + self.assertEqual(document.GraphicObjects.getCount(), 2) self.ui_test.close_doc() + # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sw/source/core/access/accframebase.cxx b/sw/source/core/access/accframebase.cxx index fba6ca85fcc6..cfbfe9ecf678 100644 --- a/sw/source/core/access/accframebase.cxx +++ b/sw/source/core/access/accframebase.cxx @@ -319,8 +319,7 @@ bool SwAccessibleFrameBase::GetSelectedState( ) } else if( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA ) { - if( ((nHere > nStartIndex) || pStart->nContent.GetIndex() ==0 ) - && (nHere < nEndIndex ) ) + if (IsSelectFrameAnchoredAtPara(*pPos, *pStart, *pEnd)) return true; } else if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index df641292b4f0..0662ec7ddf26 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -1283,19 +1283,17 @@ void SwAccessibleMap::InvalidateShapeInParaSelection() } else if( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA ) { - if (((nStartIndex < nFirstNode) || - (nFirstNode == nStartIndex && pStart->nContent.GetIndex() == 0)) - && (nLastNode < nEndIndex)) + uno::Reference<XAccessible> const xAcc((*aIter).second); + if (xAcc.is()) { - uno::Reference < XAccessible > xAcc( (*aIter).second ); - if( xAcc.is() ) + if (IsSelectFrameAnchoredAtPara(*pPos, *pStart, *pEnd)) + { static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->SetState( AccessibleStateType::SELECTED ); - } - else - { - uno::Reference < XAccessible > xAcc( (*aIter).second ); - if(xAcc.is()) + } + else + { static_cast < ::accessibility::AccessibleShape* >(xAcc.get())->ResetState( AccessibleStateType::SELECTED ); + } } } else if (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 731bac5b7b49..4b9ee39a1ed4 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -3466,9 +3466,11 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( ++nStart; break; case RndStdIds::FLY_AT_PARA: - // FIXME TODO why exclude start node, this seems very questionable and causes data loss on export - if(m_rDoc.getIDocumentRedlineAccess().IsRedlineMove()) - ++nStart; + { + bAdd = IsSelectFrameAnchoredAtPara(*pAPos, + pCopiedPaM ? *pCopiedPaM->Start() : SwPosition(rRg.aStart), + pCopiedPaM ? *pCopiedPaM->End() : SwPosition(rRg.aEnd)); + } break; case RndStdIds::FLY_AT_CHAR: { @@ -3480,7 +3482,7 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( default: continue; } - if (RndStdIds::FLY_AT_CHAR != pAnchor->GetAnchorId()) + if (RndStdIds::FLY_AT_FLY == pAnchor->GetAnchorId()) { if (nStart > nSkipAfter) continue; @@ -3495,31 +3497,6 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl( bAdd = true; if (!bAdd && !m_rDoc.getIDocumentRedlineAccess().IsRedlineMove()) // fdo#40599: not for redline move { - bool bEmptyNode = false; - bool bLastNode = false; - // is the node empty? - const SwNodes& rNodes = pAPos->nNode.GetNodes(); - SwTextNode *const pTextNode = pAPos->nNode.GetNode().GetTextNode(); - if (nullptr != pTextNode) - { - bEmptyNode = pTextNode->GetText().isEmpty(); - if (bEmptyNode) - { - //last node information is only necessary to know for the last TextNode - SwNodeIndex aTmp( pAPos->nNode ); - ++aTmp;//goto next node - while (aTmp.GetNode().IsEndNode()) - { - if (aTmp == rNodes.GetEndOfContent().GetIndex()) - { - bLastNode = true; - break; - } - ++aTmp; - } - } - } - bAdd = bLastNode && bEmptyNode; if (!bAdd) { // technically old code checked nContent of AT_FLY which is pointless @@ -4857,6 +4834,8 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo // at-char anchors post SplitNode are on index 0 of 2nd node and will // remain there - move them back to the start (end would also work?) + // ... also for at-para anchors; here start is preferable because + // it's consistent with SplitNode from SwUndoInserts::RedoImpl() if (pFlysAtInsPos) { // init *again* - because CopyWithFlyInFly moved startPos @@ -4869,6 +4848,8 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo startPos = *temp.GetPoint(); } assert(startPos.nNode.GetNode().IsContentNode()); + SwPosition startPosAtPara(startPos); + startPosAtPara.nContent.Assign(nullptr, 0); for (SwFrameFormat * pFly : *pFlysAtInsPos) { @@ -4879,6 +4860,12 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo anchor.SetAnchor( &startPos ); pFly->SetFormatAttr(anchor); } + if (pAnchor->GetAnchorId() == RndStdIds::FLY_AT_PARA) + { + SwFormatAnchor anchor(*pAnchor); + anchor.SetAnchor( &startPosAtPara ); + pFly->SetFormatAttr(anchor); + } } } diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx index 3cc2e8b6144c..7edd87e12850 100644 --- a/sw/source/core/doc/docedt.cxx +++ b/sw/source/core/doc/docedt.cxx @@ -138,14 +138,14 @@ void SaveFlyInRange( const SwPaM& rPam, const SwPosition& rInsPos, const SwPosition* pPos = rPam.Start(); const SwNodeIndex& rSttNdIdx = pPos->nNode; - short nSttOff = (!bMoveAllFlys && rSttNdIdx.GetNode().IsContentNode() && - pPos->nContent.GetIndex()) ? 1 : 0; - pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint(); - const SwNodeIndex& rEndNdIdx = pPos->nNode; - short nOff = ( bMoveAllFlys || ( rEndNdIdx.GetNode().IsContentNode() && - pPos->nContent == rEndNdIdx.GetNode().GetContentNode()->Len() )) - ? 0 : 1; + SwPosition atParaEnd(*rPam.End()); + if (bMoveAllFlys) + { + assert(rPam.End()->nContent.GetIndex() == rPam.End()->nNode.GetNode().GetTextNode()->Len()); + ++atParaEnd.nNode; + atParaEnd.nContent.Assign(atParaEnd.nNode.GetNode().GetContentNode(), 0); + } for( SwFrameFormats::size_type n = 0; n < rFormats.size(); ++n ) { @@ -163,27 +163,13 @@ void SaveFlyInRange( const SwPaM& rPam, const SwPosition& rInsPos, { bool bInsPos = false; - if (!bMoveAllFlys - && RndStdIds::FLY_AT_CHAR != pAnchor->GetAnchorId() - && rEndNdIdx == pAPos->nNode) - { - // Do not touch Anchor, if only a part of the EndNode - // or the whole EndNode is identical with the SttNode - if( rSttNdIdx != pAPos->nNode ) - { - // Only attach an anchor to the beginning or end - SwPosition aPos( rSttNdIdx ); - SwFormatAnchor aAnchor( *pAnchor ); - aAnchor.SetAnchor( &aPos ); - pFormat->SetFormatAttr( aAnchor ); - } - } - else if ( (//bMoveAllFlys ... no do not check - all callers are actually from redline code, from the MoveToSection case; so check bMoveAllFlys only for AT_PARA! - (RndStdIds::FLY_AT_CHAR == pAnchor->GetAnchorId()) + if ( (RndStdIds::FLY_AT_CHAR == pAnchor->GetAnchorId() && IsDestroyFrameAnchoredAtChar(*pAPos, *rPam.Start(), *rPam.End())) || (RndStdIds::FLY_AT_PARA == pAnchor->GetAnchorId() - && rSttNdIdx.GetIndex() + nSttOff <= pAPos->nNode.GetIndex() - && pAPos->nNode.GetIndex() <= rEndNdIdx.GetIndex() - nOff) + && IsSelectFrameAnchoredAtPara(*pAPos, *rPam.Start(), atParaEnd, + bMoveAllFlys + ? DelContentType::CheckNoCntnt|DelContentType::AllMask + : DelContentType::AllMask)) || (RndStdIds::FLY_AT_PARA == pAnchor->GetAnchorId() && (bInsPos = (rInsPos.nNode == pAPos->nNode))) || (RndStdIds::FLY_AT_CHAR == pAnchor->GetAnchorId() @@ -224,7 +210,6 @@ void DelFlyInRange( const SwNodeIndex& rMkNdIdx, : SwPosition(rMkNdIdx)); SwPosition const& rStart = mark <= point ? mark : point; SwPosition const& rEnd = mark <= point ? point : mark; - const bool bDelFwrd = rMkNdIdx.GetIndex() <= rPtNdIdx.GetIndex(); SwDoc* pDoc = rMkNdIdx.GetNode().GetDoc(); SwFrameFormats& rTable = *pDoc->GetSpzFrameFormats(); @@ -235,25 +220,14 @@ void DelFlyInRange( const SwNodeIndex& rMkNdIdx, SwPosition const*const pAPos = rAnch.GetContentAnchor(); if (pAPos && (((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) - && (bDelFwrd - ? rMkNdIdx < pAPos->nNode && pAPos->nNode <= rPtNdIdx - : rPtNdIdx <= pAPos->nNode && pAPos->nNode < rMkNdIdx)) + && IsSelectFrameAnchoredAtPara(*pAPos, rStart, rEnd, pPtIdx + ? DelContentType::AllMask + : DelContentType::AllMask|DelContentType::CheckNoCntnt)) || ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) && IsDestroyFrameAnchoredAtChar(*pAPos, rStart, rEnd, pPtIdx ? DelContentType::AllMask : DelContentType::AllMask|DelContentType::CheckNoCntnt)))) { - // Only move the Anchor?? - if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PARA) - && rPtNdIdx == pAPos->nNode ) - { - SwFormatAnchor aAnch( pFormat->GetAnchor() ); - SwPosition aPos( rMkNdIdx ); - aAnch.SetAnchor( &aPos ); - pFormat->SetFormatAttr( aAnch ); - } - else - { // If the Fly is deleted, all Flys in its content have to be deleted too. const SwFormatContent &rContent = pFormat->GetContent(); // But only fly formats own their content, not draw formats. @@ -274,7 +248,6 @@ void DelFlyInRange( const SwNodeIndex& rMkNdIdx, // DelLayoutFormat can also trigger the deletion of objects. if( i > rTable.size() ) i = rTable.size(); - } } } } diff --git a/sw/source/core/edit/edglbldc.cxx b/sw/source/core/edit/edglbldc.cxx index a49b1ca8c235..bbc10e095f80 100644 --- a/sw/source/core/edit/edglbldc.cxx +++ b/sw/source/core/edit/edglbldc.cxx @@ -325,7 +325,7 @@ bool SwEditShell::MoveGlobalDocContent( const SwGlblDocContents& rArr , aInsPos = pMyDoc->GetNodes().GetEndOfContent(); bool bRet = pMyDoc->getIDocumentContentOperations().MoveNodeRange( aRg, aInsPos, - SwMoveFlags::ALLFLYS | SwMoveFlags::CREATEUNDOOBJ ); + SwMoveFlags::CREATEUNDOOBJ ); EndAllAction(); return bRet; diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index fe131dbc51c1..b0a46504e66a 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -2584,22 +2584,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor) && ( (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR && IsDestroyFrameAnchoredAtChar(*anchoredAt, *pStartPos, *pEndPos)) || (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA - && *pStartPos <= *anchoredAt - && *anchoredAt < *pEndPos))); - if (anchoredAt != nullptr - && rAnchor.GetAnchorId() != RndStdIds::FLY_AT_CHAR - && *anchoredAt == *pEndPos) - { - const SwNodes& nodes = anchoredAt->GetDoc()->GetNodes(); - if( *pEndPos == SwPosition( nodes.GetEndOfContent())) - inSelection = true; - else - { - SwNodeIndex idx( nodes.GetEndOfContent()); - if( SwContentNode* last = SwNodes::GoPrevious( &idx )) - inSelection = *pEndPos == SwPosition( *last, last->Len()); - } - } + && IsSelectFrameAnchoredAtPara(*anchoredAt, *pStartPos, *pEndPos)))); if( inSelection ) Add( aRegion, pFly->getFrameArea() ); else if ( !pFly->IsAnLower( pStartFrame ) && diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx index ef6dc1ae90c6..7ddeb7a15e3e 100644 --- a/sw/source/core/undo/undobj.cxx +++ b/sw/source/core/undo/undobj.cxx @@ -931,7 +931,6 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark, const SwFrameFormats& rSpzArr = *pDoc->GetSpzFrameFormats(); if( !rSpzArr.empty() ) { - const bool bDelFwrd = rMark.nNode.GetIndex() <= rPoint.nNode.GetIndex(); SwFrameFormat* pFormat; const SwFormatAnchor* pAnchor; size_t n = rSpzArr.size(); @@ -965,28 +964,25 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark, case RndStdIds::FLY_AT_PARA: { pAPos = pAnchor->GetContentAnchor(); - if( pAPos ) + if (pAPos && + pStt->nNode <= pAPos->nNode && pAPos->nNode <= pEnd->nNode) { - bool bTmp; - if( DelContentType::CheckNoCntnt & nDelContentType ) - bTmp = pStt->nNode <= pAPos->nNode && pAPos->nNode < pEnd->nNode; - else - { - if (bDelFwrd) - bTmp = rMark.nNode < pAPos->nNode && - pAPos->nNode <= rPoint.nNode; - else - bTmp = rPoint.nNode <= pAPos->nNode && - pAPos->nNode < rMark.nNode; - } - - if (bTmp) - { if( !m_pHistory ) m_pHistory.reset( new SwHistory ); + if (IsSelectFrameAnchoredAtPara(*pAPos, *pStt, *pEnd, nDelContentType)) + { + m_pHistory->AddDeleteFly(*pFormat, nChainInsPos); + // reset n so that no Format is skipped + n = n >= rSpzArr.size() + ? rSpzArr.size() : n+1; + } // Moving the anchor? - if( !( DelContentType::CheckNoCntnt & nDelContentType ) && + else if (!((DelContentType::CheckNoCntnt|DelContentType::ExcludeFlyAtStartEnd) + & nDelContentType) && + // at least for calls from SwUndoDelete, + // this should work - other Undos don't + // remember the order of the cursor (rPoint.nNode.GetIndex() == pAPos->nNode.GetIndex()) // Do not try to move the anchor to a table! && rMark.nNode.GetNode().IsTextNode()) @@ -997,14 +993,6 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark, aAnch.SetAnchor( &aPos ); pFormat->SetFormatAttr( aAnch ); } - else - { - m_pHistory->AddDeleteFly(*pFormat, nChainInsPos ); - // reset n so that no Format is skipped - n = n >= rSpzArr.size() ? - rSpzArr.size() : n+1; - } - } } } break; @@ -1021,7 +1009,7 @@ void SwUndoSaveContent::DelContentIndex( const SwPosition& rMark, n = n >= rSpzArr.size() ? rSpzArr.size() : n+1; } else if (!((DelContentType::CheckNoCntnt | - DelContentType::ExcludeAtCharFlyAtStartEnd) + DelContentType::ExcludeFlyAtStartEnd) & nDelContentType)) { if( *pStt <= *pAPos && *pAPos < *pEnd ) @@ -1547,6 +1535,15 @@ static bool IsAtStartOfSection(SwPosition const& rAnchorPos) return node == rAnchorPos.nNode && rAnchorPos.nContent == 0; } +static bool IsNotBackspaceHeuristic( + SwPosition const& rStart, SwPosition const& rEnd) +{ + // check if the selection is backspace/delete created by DelLeft/DelRight + return rStart.nNode.GetIndex() + 1 != rEnd.nNode.GetIndex() + || rEnd.nContent != 0 + || rStart.nContent != rStart.nNode.GetNode().GetTextNode()->Len(); +} + bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos, SwPosition const & rStart, SwPosition const & rEnd, DelContentType const nDelContentType) @@ -1566,16 +1563,57 @@ bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos, // in general, exclude the start and end position return ((rStart < rAnchorPos) || (rStart == rAnchorPos - && !(nDelContentType & DelContentType::ExcludeAtCharFlyAtStartEnd) + && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd) // special case: fully deleted node && ((rStart.nNode != rEnd.nNode && rStart.nContent == 0) || IsAtStartOfSection(rAnchorPos)))) && ((rAnchorPos < rEnd) || (rAnchorPos == rEnd - && !(nDelContentType & DelContentType::ExcludeAtCharFlyAtStartEnd) + && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd) // special case: fully deleted node && ((rEnd.nNode != rStart.nNode && rEnd.nContent == rEnd.nNode.GetNode().GetTextNode()->Len()) || IsAtEndOfSection(rAnchorPos)))); } +bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos, + SwPosition const & rStart, SwPosition const & rEnd, + DelContentType const nDelContentType) +{ + assert(rStart <= rEnd); + + // CheckNoCntnt means DelFullPara which is obvious to handle + if (DelContentType::CheckNoCntnt & nDelContentType) + { // exclude selection end node because it won't be deleted + return (rAnchorPos.nNode < rEnd.nNode) + && (rStart.nNode <= rAnchorPos.nNode); + } + + if (rAnchorPos.GetDoc()->IsInReading()) + { // FIXME hack for writerfilter RemoveLastParagraph(); can't test file format more specific? + // but it MUST NOT be done during the SetRedlineFlags at the end of ODF + // import, where the IsInXMLImport() cannot be checked because the + // stupid code temp. overrides it - instead rely on setting the ALLFLYS + // flag in MoveFromSection() and converting that to CheckNoCntnt with + // adjusted cursor! + return (rStart.nNode < rAnchorPos.nNode) && (rAnchorPos.nNode < rEnd.nNode); + } + + // in general, exclude the start and end position + return ((rStart.nNode < rAnchorPos.nNode) + || (rStart.nNode == rAnchorPos.nNode + && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd) + // special case: fully deleted node + && ((rStart.nNode != rEnd.nNode && rStart.nContent == 0 + // but not if the selection is backspace/delete! + && IsNotBackspaceHeuristic(rStart, rEnd)) + || IsAtStartOfSection(rStart)))) + && ((rAnchorPos.nNode < rEnd.nNode) + || (rAnchorPos.nNode == rEnd.nNode + && !(nDelContentType & DelContentType::ExcludeFlyAtStartEnd) + // special case: fully deleted node + && ((rEnd.nNode != rStart.nNode && rEnd.nContent == rEnd.nNode.GetNode().GetTextNode()->Len() + && IsNotBackspaceHeuristic(rStart, rEnd)) + || IsAtEndOfSection(rEnd)))); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/undo/untblk.cxx b/sw/source/core/undo/untblk.cxx index 46f7b7a769c5..365736807059 100644 --- a/sw/source/core/undo/untblk.cxx +++ b/sw/source/core/undo/untblk.cxx @@ -200,15 +200,14 @@ SwUndoInserts::~SwUndoInserts() // But storing absolute indices leads to crashes if some action in Undo fails to roll back some modifications. // Has following main steps: -// 1. DelContentIndex to delete footnotes, flys, bookmarks (see comment for this function) +// 1. m_FlyUndos removes flys anchored to first and last paragraph in Undo range. +// This array may be empty. +// 2. DelContentIndex to delete footnotes, flys, bookmarks (see comment for this function) // Deleted flys are stored in pHistory array. -// First and last paragraphs flys are handled later in this function! They are not deleted by DelContentIndex! -// For flys anchored to last paragraph, DelContentIndex re-anchors them to the last paragraph that will remain after Undo. -// This is not fully correct, as everything between nSttNode and nEndNode should be deleted (these nodes marks range of inserted nodes). -// But due to bug in paste (probably there), during paste all flys are anchored to last paragraph (see https://bugs.documentfoundation.org/show_bug.cgi?id=94225#c38). -// So they should be re-anchored. -// 2. MoveToUndoNds moves nodes to Undo nodes array and removes them from document. -// 3. m_FlyUndos removes flys anchored to first and last paragraph in Undo range. This array may be empty. +// First and last paragraphs flys are not deleted by DelContentIndex! +// For flys anchored to last paragraph, DelContentIndex re-anchors them to +// the last paragraph that will remain after Undo. +// 3. MoveToUndoNds moves nodes to Undo nodes array and removes them from document. // 4. Lastly (starting from if(pTextNode)), text from last paragraph is joined to last remaining paragraph and FormatColl for last paragraph is restored. // Format coll for last paragraph is removed during execution of UndoImpl @@ -266,7 +265,7 @@ void SwUndoInserts::UndoImpl(::sw::UndoRedoContext & rContext) m_nSetPos = m_pHistory->Count(); sal_uLong nTmp = rPam.GetMark()->nNode.GetIndex(); DelContentIndex(*rPam.GetMark(), *rPam.GetPoint(), - DelContentType::AllMask|DelContentType::ExcludeAtCharFlyAtStartEnd); + DelContentType::AllMask|DelContentType::ExcludeFlyAtStartEnd); m_nNodeDiff += nTmp - rPam.GetMark()->nNode.GetIndex(); if( *rPam.GetPoint() != *rPam.GetMark() ) { |