summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--offapi/UnoApi_offapi.mk1
-rw-r--r--offapi/com/sun/star/datatransfer/XTransferableTextSupplier.idl44
-rw-r--r--sw/inc/unotextrange.hxx16
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx9
-rw-r--r--sw/qa/extras/unowriter/data/tdf134250.fodt86
-rw-r--r--sw/qa/extras/unowriter/data/tdf134252.fodt95
-rw-r--r--sw/qa/extras/unowriter/unowriter.cxx122
-rw-r--r--sw/source/core/unocore/unoobj2.cxx163
-rw-r--r--sw/source/core/unocore/unosect.cxx25
-rw-r--r--sw/source/core/unocore/unotbl.cxx3
-rw-r--r--sw/source/uibase/dochdl/swdtflvr.cxx95
-rw-r--r--sw/source/uibase/inc/swdtflvr.hxx2
-rw-r--r--sw/source/uibase/inc/unotxvw.hxx5
-rw-r--r--sw/source/uibase/uno/unotxvw.cxx29
14 files changed, 654 insertions, 41 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 8d6e21d00a9b..eabb1272588a 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -2132,6 +2132,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/datatransfer,\
XTransferableEx \
XTransferableSource \
XTransferableSupplier \
+ XTransferableTextSupplier \
))
$(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/datatransfer/clipboard,\
ClipboardEvent \
diff --git a/offapi/com/sun/star/datatransfer/XTransferableTextSupplier.idl b/offapi/com/sun/star/datatransfer/XTransferableTextSupplier.idl
new file mode 100644
index 000000000000..7d91ec9f0c41
--- /dev/null
+++ b/offapi/com/sun/star/datatransfer/XTransferableTextSupplier.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#ifndef __com_sun_star_datatransfer_XTransferableTextSupplier_idl__
+#define __com_sun_star_datatransfer_XTransferableTextSupplier_idl__
+
+#include <com/sun/star/datatransfer/XTransferable.idl>
+#include <com/sun/star/text/XTextRange.idl>
+
+
+module com { module sun { module star { module datatransfer {
+
+/** @since LO 7.2
+ */
+interface XTransferableTextSupplier
+{
+ /** Provide access to a transferable representation of a given text
+ range.
+
+ @param xRange a text range known to the supplier.
+
+ @returns
+ a transferable object representing the given text range.
+
+ @see com::sun::star::datatransfer::XTransferable
+ */
+ XTransferable getTransferableForTextRange(
+ [in] com::sun::star::text::XTextRange xRange);
+
+};
+
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx
index 41a69049fc5e..471a9ae8bc3e 100644
--- a/sw/inc/unotextrange.hxx
+++ b/sw/inc/unotextrange.hxx
@@ -55,10 +55,16 @@ public:
namespace sw {
+ enum class TextRangeMode {
+ RequireTextNode,
+ AllowNonTextNode
+ };
+
void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget);
SW_DLLPUBLIC bool XTextRangeToSwPaM(SwUnoInternalPaM& rToFill,
- const css::uno::Reference< css::text::XTextRange > & xTextRange);
+ const css::uno::Reference<css::text::XTextRange> & xTextRange,
+ TextRangeMode eMode = TextRangeMode::RequireTextNode);
css::uno::Reference< css::text::XText >
CreateParentXText(SwDoc & rDoc, const SwPosition& rPos);
@@ -95,6 +101,7 @@ private:
RANGE_IN_TEXT, // "ordinary" css::text::TextRange
RANGE_IN_CELL, // position created with a cell that has no uno object
RANGE_IS_TABLE, // anchor of a table
+ RANGE_IS_SECTION, // anchor of a section
};
void SetPositions(SwPaM const& rPam);
@@ -112,11 +119,14 @@ public:
const css::uno::Reference< css::text::XText > & xParent,
const enum RangePosition eRange = RANGE_IN_TEXT);
// only for RANGE_IS_TABLE
- SwXTextRange(SwFrameFormat& rTableFormat);
+ SwXTextRange(SwTableFormat& rTableFormat);
+ // only for RANGE_IS_SECTION
+ SwXTextRange(SwSectionFormat& rSectionFormat);
const SwDoc& GetDoc() const;
SwDoc& GetDoc();
- bool GetPositions(SwPaM & rToFill) const;
+ bool GetPositions(SwPaM & rToFill,
+ ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode) const;
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(
SwDoc & rDoc,
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 9e88e37f2aaa..8190ef8834ca 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -1374,7 +1374,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf134250)
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
uno::Reference<text::XTextContent> xTextContent(xSections->getByIndex(0), uno::UNO_QUERY);
- CPPUNIT_ASSERT(xTextContent->getAnchor()->getString().endsWith("bar"));
+ CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
+ xTextContent->getAnchor()->getString());
// select all with table at start -> 3 times
dispatchCommand(mxComponent, ".uno:SelectAll", {});
@@ -1403,7 +1404,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf134250)
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
// Without the fix in place, section's content would have been gone after undo
- CPPUNIT_ASSERT(xTextContent->getAnchor()->getString().endsWith("bar"));
+ CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
+ xTextContent->getAnchor()->getString());
dispatchCommand(mxComponent, ".uno:Redo", {});
Scheduler::ProcessEventsToIdle();
@@ -1416,7 +1418,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf134250)
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
- CPPUNIT_ASSERT(xTextContent->getAnchor()->getString().endsWith("bar"));
+ CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"),
+ xTextContent->getAnchor()->getString());
dispatchCommand(mxComponent, ".uno:Redo", {});
Scheduler::ProcessEventsToIdle();
diff --git a/sw/qa/extras/unowriter/data/tdf134250.fodt b/sw/qa/extras/unowriter/data/tdf134250.fodt
new file mode 100644
index 000000000000..86aaa140c9e7
--- /dev/null
+++ b/sw/qa/extras/unowriter/data/tdf134250.fodt
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" 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:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field: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:xforms="http://www.w3.org/2002/xforms" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Source Han Serif CN" svg:font-family="&apos;Source Han Serif CN&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="#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" 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="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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"/>
+ </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: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"/>
+ </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="17cm" style:rel-column-width="65535*"/>
+ </style:style>
+ <style:style style:name="Table1.A1" style:family="table-cell">
+ <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/>
+ </style:style>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties officeooo:rsid="001fe5a9" officeooo:paragraph-rsid="001fe5a9"/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table_20_Contents">
+ <style:text-properties officeooo:rsid="001fe5a9" officeooo:paragraph-rsid="001fe5a9"/>
+ </style:style>
+ <style:style style:name="T1" style:family="text">
+ <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
+ </style:style>
+ <style:style style:name="Sect1" style:family="section">
+ <style:section-properties style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </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">
+ <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:section text:style-name="Sect1" text:name="Section1">
+ <table:table table:name="Table1" table:style-name="Table1">
+ <table:table-column table:style-name="Table1.A"/>
+ <table:table-row>
+ <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+ <text:p text:style-name="P2">foo</text:p>
+ </table:table-cell>
+ </table:table-row>
+ </table:table>
+ <text:p text:style-name="P1">b<text:span text:style-name="T1">a</text:span><text:bookmark text:name="Bookmark 1"/>r</text:p>
+ </text:section>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/unowriter/data/tdf134252.fodt b/sw/qa/extras/unowriter/data/tdf134252.fodt
new file mode 100644
index 000000000000..6e19ac847dd8
--- /dev/null
+++ b/sw/qa/extras/unowriter/data/tdf134252.fodt
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" 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:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field: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:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Source Han Serif CN" svg:font-family="&apos;Source Han Serif CN&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="#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" 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="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" 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"/>
+ </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"/>
+ <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"/>
+ </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="17cm" style:rel-column-width="65535*"/>
+ </style:style>
+ <style:style style:name="Table1.A1" style:family="table-cell">
+ <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/>
+ </style:style>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties officeooo:rsid="00078615" officeooo:paragraph-rsid="00078615"/>
+ </style:style>
+ <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Table_20_Contents">
+ <style:text-properties officeooo:rsid="00095b34" officeooo:paragraph-rsid="00095b34"/>
+ </style:style>
+ <style:style style:name="Sect1" style:family="section">
+ <style:section-properties fo:background-color="#81d41a" style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ <style:background-image/>
+ </style:section-properties>
+ </style:style>
+ <style:style style:name="Sect2" style:family="section">
+ <style:section-properties style:editable="false">
+ <style:columns fo:column-count="1" fo:column-gap="0cm"/>
+ </style:section-properties>
+ </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="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>
+ <text:section text:style-name="Sect1" text:name="Section1">
+ <text:p text:style-name="P1">bar</text:p>
+ <table:table table:name="Table1" table:style-name="Table1">
+ <table:table-column table:style-name="Table1.A"/>
+ <table:table-row>
+ <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+ <text:p text:style-name="P3">baz</text:p>
+ </table:table-cell>
+ </table:table-row>
+ </table:table>
+ </text:section>
+ <text:section text:style-name="Sect2" text:name="Section2">
+ <text:p text:style-name="P1">foo</text:p>
+ </text:section>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index a316f3485777..a3cf7afaa37e 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -10,6 +10,8 @@
#include <swmodeltestbase.hxx>
#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/datatransfer/XTransferableSupplier.hpp>
+#include <com/sun/star/datatransfer/XTransferableTextSupplier.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/text/AutoTextContainer.hpp>
@@ -374,6 +376,126 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXAutoTextGroup)
xAutoTextContainer->removeByName(sGroupName);
}
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTableAtStart)
+{
+ // this contains a section that starts with a table
+ load(DATA_DIRECTORY, "tdf134250.fodt");
+
+ uno::Reference<text::XTextTablesSupplier> const xTextTablesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> const xTables(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+ uno::Reference<text::XTextSectionsSupplier> const xTextSectionsSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> const xSections(
+ xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
+
+ uno::Reference<text::XTextContent> const xSection(xSections->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> const xAnchor(xSection->getAnchor());
+ CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"), xAnchor->getString());
+
+ // copy the content of the section to a clipboard document
+ uno::Reference<datatransfer::XTransferableSupplier> const xTS(
+ uno::Reference<frame::XModel>(mxComponent, uno::UNO_QUERY_THROW)->getCurrentController(),
+ uno::UNO_QUERY);
+ uno::Reference<datatransfer::XTransferableTextSupplier> const xTTS(xTS, uno::UNO_QUERY);
+ uno::Reference<datatransfer::XTransferable> const xTransferable(
+ xTTS->getTransferableForTextRange(xAnchor));
+
+ // check this doesn't throw
+ CPPUNIT_ASSERT(xAnchor->getStart().is());
+ CPPUNIT_ASSERT(xAnchor->getEnd().is());
+
+ // replace section content
+ xAnchor->setString("quux");
+
+ // table in section was deleted, but not section itself
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("\""
+ "quux" /*SAL_NEWLINE_STRING*/ "\""),
+ OUString("\"" + xAnchor->getString() + "\""));
+
+ // now paste it
+ uno::Reference<text::XTextViewCursorSupplier> const xTVCS(xTS, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursor> const xCursor(xTVCS->getViewCursor());
+ xCursor->gotoEnd(false);
+ xTS->insertTransferable(xTransferable);
+
+ // table in section was pasted, but not section itself
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount());
+ xCursor->gotoStart(true);
+ CPPUNIT_ASSERT_EQUAL(OUString("quux" SAL_NEWLINE_STRING "foo" SAL_NEWLINE_STRING "bar"),
+ xCursor->getString());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTableAtEnd)
+{
+ // this contains a section that ends with a table (plus another section)
+ load(DATA_DIRECTORY, "tdf134252.fodt");
+
+ uno::Reference<text::XTextTablesSupplier> const xTextTablesSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> const xTables(xTextTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+ uno::Reference<text::XTextSectionsSupplier> const xTextSectionsSupplier(mxComponent,
+ uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> const xSections(
+ xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
+
+ uno::Reference<text::XTextContent> const xSection(xSections->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> const xAnchor(xSection->getAnchor());
+ CPPUNIT_ASSERT_EQUAL(OUString("bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING),
+ xAnchor->getString());
+
+ // copy the content of the section to a clipboard document
+ uno::Reference<datatransfer::XTransferableSupplier> const xTS(
+ uno::Reference<frame::XModel>(mxComponent, uno::UNO_QUERY_THROW)->getCurrentController(),
+ uno::UNO_QUERY);
+ uno::Reference<datatransfer::XTransferableTextSupplier> const xTTS(xTS, uno::UNO_QUERY);
+ uno::Reference<datatransfer::XTransferable> const xTransferable(
+ xTTS->getTransferableForTextRange(xAnchor));
+
+ // check this doesn't throw
+ CPPUNIT_ASSERT(xAnchor->getStart().is());
+ CPPUNIT_ASSERT(xAnchor->getEnd().is());
+
+ // replace section content
+ xAnchor->setString("quux");
+
+ // table in section was deleted, but not section itself
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("\""
+ "quux" /*SAL_NEWLINE_STRING*/ "\""),
+ OUString("\"" + xAnchor->getString() + "\""));
+
+ // now paste it
+ uno::Reference<text::XTextViewCursorSupplier> const xTVCS(xTS, uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursor> const xCursor(xTVCS->getViewCursor());
+ xCursor->gotoEnd(false);
+ xTS->insertTransferable(xTransferable);
+
+ // table in section was pasted, but not section itself
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount());
+ // note: this selects the 2nd section because it calls StartOfSection()
+ // not SttEndDoc() like it should?
+ xCursor->gotoStart(true);
+ CPPUNIT_ASSERT_EQUAL(OUString(/*"quux" SAL_NEWLINE_STRING */
+ "foobar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING),
+ xCursor->getString());
+}
+
CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXURI)
{
uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index e364bb353f92..63dc5a50d392 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -650,20 +650,23 @@ public:
const enum RangePosition m_eRangePosition;
SwDoc& m_rDoc;
uno::Reference<text::XText> m_xParentText;
- const SwFrameFormat* m_pTableFormat;
+ const SwFrameFormat* m_pTableOrSectionFormat;
const ::sw::mark::IMark* m_pMark;
Impl(SwDoc& rDoc, const enum RangePosition eRange,
- SwFrameFormat* const pTableFormat,
+ SwFrameFormat* const pTableOrSectionFormat,
const uno::Reference<text::XText>& xParent = nullptr)
: m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR))
, m_eRangePosition(eRange)
, m_rDoc(rDoc)
, m_xParentText(xParent)
- , m_pTableFormat(pTableFormat)
+ , m_pTableOrSectionFormat(pTableOrSectionFormat)
, m_pMark(nullptr)
{
- m_pTableFormat && StartListening(pTableFormat->GetNotifier());
+ if (m_pTableOrSectionFormat)
+ {
+ StartListening(pTableOrSectionFormat->GetNotifier());
+ }
}
virtual ~Impl() override
@@ -679,7 +682,7 @@ public:
m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark);
m_pMark = nullptr;
}
- m_pTableFormat = nullptr;
+ m_pTableOrSectionFormat = nullptr;
EndListeningAll();
}
@@ -687,7 +690,7 @@ public:
void SetMark(::sw::mark::IMark& rMark)
{
EndListeningAll();
- m_pTableFormat = nullptr;
+ m_pTableOrSectionFormat = nullptr;
m_pMark = &rMark;
StartListening(rMark.GetNotifier());
}
@@ -701,7 +704,7 @@ void SwXTextRange::Impl::Notify(const SfxHint& rHint)
if(rHint.GetId() == SfxHintId::Dying)
{
EndListeningAll();
- m_pTableFormat = nullptr;
+ m_pTableOrSectionFormat = nullptr;
m_pMark = nullptr;
}
}
@@ -714,7 +717,7 @@ SwXTextRange::SwXTextRange(SwPaM const & rPam,
SetPositions(rPam);
}
-SwXTextRange::SwXTextRange(SwFrameFormat& rTableFormat)
+SwXTextRange::SwXTextRange(SwTableFormat& rTableFormat)
: m_pImpl(
new SwXTextRange::Impl(*rTableFormat.GetDoc(), RANGE_IS_TABLE, &rTableFormat) )
{
@@ -726,6 +729,13 @@ SwXTextRange::SwXTextRange(SwFrameFormat& rTableFormat)
SetPositions( aPam );
}
+SwXTextRange::SwXTextRange(SwSectionFormat& rSectionFormat)
+ : m_pImpl(
+ new SwXTextRange::Impl(*rSectionFormat.GetDoc(), RANGE_IS_SECTION, &rSectionFormat) )
+{
+ // no SetPositions here for now
+}
+
SwXTextRange::~SwXTextRange()
{
}
@@ -753,6 +763,18 @@ void SwXTextRange::SetPositions(const SwPaM& rPam)
m_pImpl->SetMark(*pMark);
}
+static void DeleteTable(SwDoc & rDoc, SwTable& rTable)
+{
+ SwSelBoxes aSelBoxes;
+ for (auto& rBox : rTable.GetTabSortBoxes())
+ {
+ aSelBoxes.insert(rBox);
+ }
+ // note: if the table is the content in the section, this will create
+ // a new text node - that's desirable here
+ rDoc.DeleteRowCol(aSelBoxes);
+}
+
void SwXTextRange::DeleteAndInsert(
const OUString& rText, const bool bForceExpandHints)
{
@@ -764,11 +786,80 @@ void SwXTextRange::DeleteAndInsert(
const SwPosition aPos(GetDoc().GetNodes().GetEndOfContent());
SwCursor aCursor(aPos, nullptr);
- if (!GetPositions(aCursor))
- return;
UnoActionContext aAction(& m_pImpl->m_rDoc);
- m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition)
+ {
+ if (!m_pImpl->m_pTableOrSectionFormat)
+ {
+ throw uno::RuntimeException("disposed?");
+ }
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ SwSectionFormat const& rFormat(
+ *static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ SwNodeIndex const start(*rFormat.GetSectionNode());
+ SwNodeIndex const end(*start.GetNode().EndOfSectionNode());
+
+ // delete tables at start
+ for (SwNodeIndex i = start; i < end; )
+ {
+ SwNode & rNode(i.GetNode());
+ if (rNode.IsSectionNode())
+ {
+ ++i;
+ continue;
+ }
+ else if (SwTableNode *const pTableNode = rNode.GetTableNode())
+ {
+ DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable());
+ // where does that leave index? presumably behind?
+ }
+ else
+ {
+ assert(rNode.IsTextNode());
+ break;
+ }
+ }
+ // delete tables at end
+ for (SwNodeIndex i = end; start <= i; )
+ {
+ --i;
+ SwNode & rNode(i.GetNode());
+ if (rNode.IsEndNode())
+ {
+ if (SwTableNode *const pTableNode = rNode.StartOfSectionNode()->GetTableNode())
+ {
+ DeleteTable(m_pImpl->m_rDoc, pTableNode->GetTable());
+ }
+ else
+ {
+ assert(rNode.StartOfSectionNode()->IsSectionNode());
+ continue;
+ }
+ }
+ else
+ {
+ assert(rNode.IsTextNode());
+ break;
+ }
+ }
+ // now there should be a text node at the start and end of it!
+ *aCursor.GetPoint() = SwPosition(start);
+ aCursor.Move( fnMoveForward, GoInContent );
+ assert(aCursor.GetPoint()->nNode <= end);
+ aCursor.SetMark();
+ *aCursor.GetPoint() = SwPosition(end);
+ aCursor.Move( fnMoveBackward, GoInContent );
+ assert(start <= aCursor.GetPoint()->nNode);
+ }
+ else
+ {
+ if (!GetPositions(aCursor))
+ return;
+ m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+ }
+
if (aCursor.HasMark())
{
m_pImpl->m_rDoc.getIDocumentContentOperations().DeleteAndJoin(aCursor);
@@ -836,9 +927,9 @@ SwXTextRange::getText()
if (!m_pImpl->m_xParentText.is())
{
if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE &&
- m_pImpl->m_pTableFormat)
+ m_pImpl->m_pTableOrSectionFormat)
{
- SwTable const*const pTable = SwTable::FindTable( m_pImpl->m_pTableFormat );
+ SwTable const*const pTable = SwTable::FindTable( m_pImpl->m_pTableOrSectionFormat );
SwTableNode const*const pTableNode = pTable->GetTableNode();
const SwPosition aPosition( *pTableNode );
m_pImpl->m_xParentText =
@@ -870,6 +961,15 @@ SwXTextRange::getStart()
// start and end are this, if it's a table
xRet = this;
}
+ else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+ && m_pImpl->m_pTableOrSectionFormat)
+ {
+ auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx());
+ aPaM.Move( fnMoveForward, GoInContent );
+ assert(aPaM.GetPoint()->nNode < *pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText);
+ }
else
{
throw uno::RuntimeException("disposed?");
@@ -898,6 +998,15 @@ SwXTextRange::getEnd()
// start and end are this, if it's a table
xRet = this;
}
+ else if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+ && m_pImpl->m_pTableOrSectionFormat)
+ {
+ auto const pSectFormat(static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat));
+ SwPaM aPaM(*pSectFormat->GetContent().GetContentIdx()->GetNode().EndOfSectionNode());
+ aPaM.Move( fnMoveBackward, GoInContent );
+ assert(*pSectFormat->GetContent().GetContentIdx() < aPaM.GetPoint()->nNode);
+ xRet = new SwXTextRange(aPaM, m_pImpl->m_xParentText);
+ }
else
{
throw uno::RuntimeException("disposed?");
@@ -913,7 +1022,7 @@ OUString SAL_CALL SwXTextRange::getString()
// for tables there is no bookmark, thus also no text
// one could export the table as ASCII here maybe?
SwPaM aPaM(GetDoc().GetNodes());
- if (GetPositions(aPaM) && aPaM.HasMark())
+ if (GetPositions(aPaM, sw::TextRangeMode::AllowNonTextNode) && aPaM.HasMark())
{
SwUnoCursorHelper::GetTextFromPam(aPaM, sRet);
}
@@ -927,8 +1036,27 @@ void SAL_CALL SwXTextRange::setString(const OUString& rString)
DeleteAndInsert(rString, false);
}
-bool SwXTextRange::GetPositions(SwPaM& rToFill) const
+bool SwXTextRange::GetPositions(SwPaM& rToFill, ::sw::TextRangeMode const eMode) const
{
+ if (RANGE_IS_SECTION == m_pImpl->m_eRangePosition
+ && eMode == ::sw::TextRangeMode::AllowNonTextNode)
+ {
+ if (auto const pSectFormat = static_cast<SwSectionFormat const*>(m_pImpl->m_pTableOrSectionFormat))
+ {
+ SwNodeIndex const*const pSectionNode(pSectFormat->GetContent().GetContentIdx());
+ assert(pSectionNode);
+ assert(pSectionNode->GetNodes().IsDocNodes());
+ rToFill.GetPoint()->nNode = *pSectionNode;
+ ++rToFill.GetPoint()->nNode;
+ rToFill.GetPoint()->nContent.Assign(rToFill.GetPoint()->nNode.GetNode().GetContentNode(), 0);
+ rToFill.SetMark();
+ rToFill.GetMark()->nNode = *pSectionNode->GetNode().EndOfSectionNode();
+ --rToFill.GetMark()->nNode;
+ rToFill.GetMark()->nContent.Assign(rToFill.GetMark()->nNode.GetNode().GetContentNode(),
+ rToFill.GetMark()->nNode.GetNode().GetContentNode() ? rToFill.GetMark()->nNode.GetNode().GetContentNode()->Len() : 0);
+ return true;
+ }
+ }
::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark();
if(pBkmk)
{
@@ -950,7 +1078,8 @@ bool SwXTextRange::GetPositions(SwPaM& rToFill) const
namespace sw {
bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
- const uno::Reference< text::XTextRange > & xTextRange)
+ const uno::Reference<text::XTextRange> & xTextRange,
+ ::sw::TextRangeMode const eMode)
{
bool bRet = false;
@@ -984,7 +1113,7 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill,
}
if(pRange && &pRange->GetDoc() == &rToFill.GetDoc())
{
- bRet = pRange->GetPositions(rToFill);
+ bRet = pRange->GetPositions(rToFill, eMode);
}
else
{
diff --git a/sw/source/core/unocore/unosect.cxx b/sw/source/core/unocore/unosect.cxx
index 3c0eb298b079..a0c158cc2897 100644
--- a/sw/source/core/unocore/unosect.cxx
+++ b/sw/source/core/unocore/unosect.cxx
@@ -457,14 +457,35 @@ SwXTextSection::getAnchor()
nullptr != ( pIdx = pSectFormat->GetContent().GetContentIdx() ) &&
pIdx->GetNode().GetNodes().IsDocNodes() )
{
+ bool isMoveIntoTable(false);
SwPaM aPaM(*pIdx);
aPaM.Move( fnMoveForward, GoInContent );
+ assert(pIdx->GetNode().IsSectionNode());
+ if (aPaM.GetPoint()->nNode.GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
+ || aPaM.GetPoint()->nNode.GetNode().FindSectionNode() != &pIdx->GetNode())
+ {
+ isMoveIntoTable = true;
+ }
const SwEndNode* pEndNode = pIdx->GetNode().EndOfSectionNode();
SwPaM aEnd(*pEndNode);
aEnd.Move( fnMoveBackward, GoInContent );
- xRet = SwXTextRange::CreateXTextRange(*pSectFormat->GetDoc(),
- *aPaM.Start(), aEnd.Start());
+ if (aEnd.GetPoint()->nNode.GetNode().FindTableNode() != pIdx->GetNode().FindTableNode()
+ || aEnd.GetPoint()->nNode.GetNode().FindSectionNode() != &pIdx->GetNode())
+ {
+ isMoveIntoTable = true;
+ }
+ if (isMoveIntoTable)
+ {
+ uno::Reference<text::XText> const xParentText(
+ ::sw::CreateParentXText(*pSectFormat->GetDoc(), SwPosition(*pIdx)));
+ xRet = new SwXTextRange(*pSectFormat);
+ }
+ else // for compatibility, keep the old way in this case
+ {
+ xRet = SwXTextRange::CreateXTextRange(*pSectFormat->GetDoc(),
+ *aPaM.Start(), aEnd.Start());
+ }
}
}
return xRet;
diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx
index 35f3eea3ad0c..c28a6a38f325 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -2179,7 +2179,8 @@ SwXTextTable::attach(const uno::Reference<text::XTextRange> & xTextRange)
uno::Reference<text::XTextRange> SwXTextTable::getAnchor()
{
SolarMutexGuard aGuard;
- SwFrameFormat* pFormat = lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this));
+ SwTableFormat *const pFormat = static_cast<SwTableFormat*>(
+ lcl_EnsureCoreConnected(GetFrameFormat(), static_cast<cppu::OWeakObject*>(this)));
return new SwXTextRange(*pFormat);
}
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index da8c13e04caa..9200cd67df9f 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -82,6 +82,7 @@
#include <IDocumentUndoRedo.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentRedlineAccess.hxx>
#include <IDocumentState.hxx>
#include <IMark.hxx>
#include <section.hxx>
@@ -867,6 +868,84 @@ void SwTransferable::DeleteSelection()
m_pWrtShell->EndUndo( SwUndoId::END );
}
+static void DeleteDDEMarks(SwDoc & rDest)
+{
+ IDocumentMarkAccess *const pMarkAccess = rDest.getIDocumentMarkAccess();
+ std::vector< ::sw::mark::IMark* > vDdeMarks;
+ // find all DDE-Bookmarks
+ for (IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
+ ppMark != pMarkAccess->getAllMarksEnd();
+ ++ppMark)
+ {
+ if (IDocumentMarkAccess::MarkType::DDE_BOOKMARK == IDocumentMarkAccess::GetType(**ppMark))
+ {
+ vDdeMarks.push_back(*ppMark);
+ }
+ }
+ // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
+ for (const auto& rpMark : vDdeMarks)
+ {
+ pMarkAccess->deleteMark(rpMark);
+ }
+}
+
+void SwTransferable::PrepareForCopyTextRange(SwPaM & rPaM)
+{
+ std::unique_ptr<SwWait> pWait;
+ if (m_pWrtShell->ShouldWait())
+ {
+ pWait.reset(new SwWait( *m_pWrtShell->GetView().GetDocShell(), true ));
+ }
+
+ m_pClpDocFac.reset(new SwDocFac);
+
+ SwDoc& rDest(lcl_GetDoc(*m_pClpDocFac));
+ rDest.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
+ {
+ SwDoc const& rSrc(*m_pWrtShell->GetDoc());
+ assert(&rSrc == &rPaM.GetDoc());
+
+ rDest.ReplaceCompatibilityOptions(rSrc);
+ rDest.ReplaceDefaults(rSrc);
+
+ //It would probably make most sense here to only insert the styles used
+ //by the selection, e.g. apply SwDoc::IsUsed on styles ?
+ rDest.ReplaceStyles(rSrc, false);
+
+ // relevant bits of rSrcWrtShell.Copy(rDest);
+ rDest.GetIDocumentUndoRedo().DoUndo(false); // always false!
+ rDest.getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines );
+
+ SwNodeIndex const aIdx(rDest.GetNodes().GetEndOfContent(), -1);
+ SwContentNode *const pContentNode(aIdx.GetNode().GetContentNode());
+ SwPosition aPos(aIdx,
+ SwIndex(pContentNode, pContentNode ? pContentNode->Len() : 0));
+
+ rSrc.getIDocumentContentOperations().CopyRange(rPaM, aPos, SwCopyFlags::CheckPosInFly);
+
+ rDest.getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::NONE );
+
+ rDest.GetMetaFieldManager().copyDocumentProperties(rSrc);
+ }
+
+ DeleteDDEMarks(rDest);
+
+ // a new one was created in core (OLE objects copied!)
+ m_aDocShellRef = rDest.GetTmpDocShell();
+ if (m_aDocShellRef.Is())
+ SwTransferable::InitOle( m_aDocShellRef );
+ rDest.SetTmpDocShell( nullptr );
+
+ // let's add some formats
+ AddFormat( SotClipboardFormatId::EMBED_SOURCE );
+ AddFormat( SotClipboardFormatId::RTF );
+#if HAVE_FEATURE_DESKTOP
+ AddFormat( SotClipboardFormatId::RICHTEXT );
+ AddFormat( SotClipboardFormatId::HTML );
+#endif
+ AddFormat( SotClipboardFormatId::STRING );
+}
+
int SwTransferable::PrepareForCopy( bool bIsCut )
{
int nRet = 1;
@@ -974,21 +1053,7 @@ int SwTransferable::PrepareForCopy( bool bIsCut )
rTmpDoc.getIDocumentFieldsAccess().LockExpFields(); // Never update fields - leave text as is
lclOverWriteDoc(*m_pWrtShell, rTmpDoc);
- {
- IDocumentMarkAccess* const pMarkAccess = rTmpDoc.getIDocumentMarkAccess();
- std::vector< ::sw::mark::IMark* > vDdeMarks;
- // find all DDE-Bookmarks
- for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getAllMarksBegin();
- ppMark != pMarkAccess->getAllMarksEnd();
- ++ppMark)
- {
- if(IDocumentMarkAccess::MarkType::DDE_BOOKMARK == IDocumentMarkAccess::GetType(**ppMark))
- vDdeMarks.push_back(*ppMark);
- }
- // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
- for(const auto& rpMark : vDdeMarks)
- pMarkAccess->deleteMark(rpMark);
- }
+ DeleteDDEMarks(rTmpDoc);
// a new one was created in CORE (OLE objects copied!)
m_aDocShellRef = rTmpDoc.GetTmpDocShell();
diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx
index e231269e7297..cdd3e2124e1e 100644
--- a/sw/source/uibase/inc/swdtflvr.hxx
+++ b/sw/source/uibase/inc/swdtflvr.hxx
@@ -40,6 +40,7 @@ class INetImage;
class SfxAbstractPasteDialog;
class SwDoc;
class SwDocFac;
+class SwPaM;
class SwTextBlocks;
class SwWrtShell;
class SvxClipboardFormatItem;
@@ -181,6 +182,7 @@ public:
int Cut();
int Copy( bool bIsCut = false );
int PrepareForCopy( bool bIsCut = false );
+ void PrepareForCopyTextRange(SwPaM & rPaM);
void CalculateAndCopy(); // special for Calculator
bool CopyGlossary( SwTextBlocks& rGlossary, const OUString& rStr );
diff --git a/sw/source/uibase/inc/unotxvw.hxx b/sw/source/uibase/inc/unotxvw.hxx
index db2f6eae398f..b31760d8f9fe 100644
--- a/sw/source/uibase/inc/unotxvw.hxx
+++ b/sw/source/uibase/inc/unotxvw.hxx
@@ -36,6 +36,7 @@
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/datatransfer/XTransferableSupplier.hpp>
+#include <com/sun/star/datatransfer/XTransferableTextSupplier.hpp>
#include <cppuhelper/implbase.hxx>
#include <svl/itemprop.hxx>
#include <TextCursorHelper.hxx>
@@ -55,6 +56,7 @@ class SwXTextView :
public css::view::XViewSettingsSupplier,
public css::beans::XPropertySet,
public css::datatransfer::XTransferableSupplier,
+ public css::datatransfer::XTransferableTextSupplier,
public SfxBaseController
{
::comphelper::OInterfaceContainerHelper2 m_SelChangedListeners;
@@ -129,6 +131,9 @@ public:
virtual css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL getTransferable( ) override;
virtual void SAL_CALL insertTransferable( const css::uno::Reference< css::datatransfer::XTransferable >& xTrans ) override;
+ // XTransferableTextSupplier
+ virtual css::uno::Reference<css::datatransfer::XTransferable> SAL_CALL getTransferableForTextRange(css::uno::Reference<css::text::XTextRange> const& xTextRange) override;
+
void NotifySelChanged();
void NotifyDBChanged();
diff --git a/sw/source/uibase/uno/unotxvw.cxx b/sw/source/uibase/uno/unotxvw.cxx
index 6a0aa7edde25..589ad2fc8644 100644
--- a/sw/source/uibase/uno/unotxvw.cxx
+++ b/sw/source/uibase/uno/unotxvw.cxx
@@ -137,6 +137,7 @@ Sequence< uno::Type > SAL_CALL SwXTextView::getTypes( )
cppu::UnoType<XRubySelection>::get(),
cppu::UnoType<XPropertySet>::get(),
cppu::UnoType<datatransfer::XTransferableSupplier>::get(),
+ cppu::UnoType<datatransfer::XTransferableTextSupplier>::get(),
SfxBaseController::getTypes()
).getTypes();
}
@@ -204,6 +205,11 @@ uno::Any SAL_CALL SwXTextView::queryInterface( const uno::Type& aType )
uno::Reference<datatransfer::XTransferableSupplier> xRet = this;
aRet <<= xRet;
}
+ else if(aType == cppu::UnoType<datatransfer::XTransferableTextSupplier>::get())
+ {
+ uno::Reference<datatransfer::XTransferableTextSupplier> xRet = this;
+ aRet <<= xRet;
+ }
else
aRet = SfxBaseController::queryInterface(aType);
return aRet;
@@ -1704,6 +1710,29 @@ SwPaM* SwXTextViewCursor::GetPaM()
return rSh.GetCursor();
}
+uno::Reference<datatransfer::XTransferable> SAL_CALL
+SwXTextView::getTransferableForTextRange(uno::Reference<text::XTextRange> const& xTextRange)
+{
+ SolarMutexGuard aGuard;
+
+ // the point is we can copy PaM that wouldn't be legal as shell cursor
+ SwUnoInternalPaM aPam(*m_pView->GetDocShell()->GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextRange, ::sw::TextRangeMode::AllowNonTextNode))
+ {
+ throw uno::RuntimeException("invalid text range");
+ }
+
+ //force immediate shell update
+ GetView()->StopShellTimer();
+ SwWrtShell& rSh = GetView()->GetWrtShell();
+ SwTransferable *const pTransfer = new SwTransferable(rSh);
+ const bool bLockedView = rSh.IsViewLocked();
+ rSh.LockView( true );
+ pTransfer->PrepareForCopyTextRange(aPam);
+ rSh.LockView( bLockedView );
+ return uno::Reference<datatransfer::XTransferable>(pTransfer);
+}
+
uno::Reference< datatransfer::XTransferable > SAL_CALL SwXTextView::getTransferable()
{
SolarMutexGuard aGuard;