summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/undobj.hxx6
-rw-r--r--sw/qa/core/uwriter.cxx3
-rw-r--r--sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odtbin0 -> 9251 bytes
-rw-r--r--sw/qa/extras/uiwriter/data/redline_fly_duplication_at_para_2nd_paragraph.fodt222
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx16
-rw-r--r--sw/qa/uitest/writer_tests4/tdf108124.py15
-rw-r--r--sw/source/core/access/accframebase.cxx3
-rw-r--r--sw/source/core/access/accmap.cxx18
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx45
-rw-r--r--sw/source/core/doc/docedt.cxx57
-rw-r--r--sw/source/core/edit/edglbldc.cxx2
-rw-r--r--sw/source/core/layout/trvlfrm.cxx17
-rw-r--r--sw/source/core/undo/undobj.cxx96
-rw-r--r--sw/source/core/undo/untblk.cxx17
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
new file mode 100644
index 000000000000..a4b41e4ec25d
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/redline_fly_at_para_one_paragraph.odt
Binary files differ
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="&apos;Courier New&apos;" 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="&apos;Arial Unicode MS&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ <style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" 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="&apos;Courier New&apos;" 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="&apos;Courier New&apos;" 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="&apos;Courier New&apos;" 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="&apos;Courier New&apos;" 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>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
+ 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() )
{