summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xmloff/txtimp.hxx4
-rw-r--r--include/xmloff/xmltoken.hxx1
-rw-r--r--schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng6
-rw-r--r--sw/qa/extras/globalfilter/data/fieldmark_QUOTE_nest.fodt133
-rw-r--r--sw/qa/extras/globalfilter/globalfilter.cxx13
-rw-r--r--sw/source/core/inc/unobookmark.hxx4
-rw-r--r--sw/source/core/unocore/unobkm.cxx19
-rw-r--r--xmloff/source/core/xmltoken.cxx1
-rw-r--r--xmloff/source/text/XMLTextMarkImportContext.cxx46
-rw-r--r--xmloff/source/text/XMLTextMarkImportContext.hxx3
-rw-r--r--xmloff/source/text/txtimp.cxx36
-rw-r--r--xmloff/source/text/txtparae.cxx14
-rw-r--r--xmloff/source/text/txtparai.cxx1
-rw-r--r--xmloff/source/token/tokens.txt1
14 files changed, 260 insertions, 22 deletions
diff --git a/include/xmloff/txtimp.hxx b/include/xmloff/txtimp.hxx
index 9259747bd94d..0124bc8eb2c2 100644
--- a/include/xmloff/txtimp.hxx
+++ b/include/xmloff/txtimp.hxx
@@ -289,7 +289,9 @@ public:
css::uno::Reference<css::text::XFormField> popFieldCtx();
void addFieldParam( const OUString& name, const OUString& value );
void setCurrentFieldParamsTo(css::uno::Reference< css::text::XFormField> const &xFormField);
- OUString getCurrentFieldType();
+ ::std::pair<OUString, OUString> getCurrentFieldType() const;
+ css::uno::Reference<css::text::XTextRange> getCurrentFieldStart() const;
+ bool hasCurrentFieldSeparator() const;
bool hasCurrentFieldCtx() const;
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 58b6329ec71a..77f9c605b707 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3308,6 +3308,7 @@ namespace xmloff::token {
// enhanced fields
XML_FIELDMARK,
XML_FIELDMARK_START,
+ XML_FIELDMARK_SEPARATOR,
XML_FIELDMARK_END,
XML_IMAGE_SCALE,
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index fcf6bfaab353..c92b5c6330bf 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2808,6 +2808,12 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:define>
<rng:define name="paragraph-content" combine="choice"
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0">
+ <rng:element name="field:fieldmark-separator">
+ <rng:empty/>
+ </rng:element>
+ </rng:define>
+ <rng:define name="paragraph-content" combine="choice"
+ xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0">
<rng:element name="field:fieldmark-end">
<rng:empty/>
</rng:element>
diff --git a/sw/qa/extras/globalfilter/data/fieldmark_QUOTE_nest.fodt b/sw/qa/extras/globalfilter/data/fieldmark_QUOTE_nest.fodt
new file mode 100644
index 000000000000..86b17a15bbce
--- /dev/null
+++ b/sw/qa/extras/globalfilter/data/fieldmark_QUOTE_nest.fodt
@@ -0,0 +1,133 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:initial-creator>Michael Stahl</meta:initial-creator><dc:creator>Michael Stahl</dc:creator><meta:editing-cycles>2</meta:editing-cycles><meta:creation-date>2019-01-24T14:48:00</meta:creation-date><dc:date>2019-01-24T14:48:00</dc:date><meta:editing-duration>P0D</meta:editing-duration><meta:generator>LibreOfficeDev/7.5.0.0.alpha0$Linux_X86_64 LibreOffice_project/be346d6cdc87b18dc861279187915de42722e970</meta:generator><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="13" meta:word-count="6" meta:character-count="24" meta:non-whitespace-character-count="18"/><meta:user-defined meta:name="AppVersion">15.0000</meta:user-defined><meta:template xlink:type="simple" xlink:actuate="onRequest" xlink:title="Normal.dotm" xlink:href=""/></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Calibri" svg:font-family="Calibri" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Calibri1" svg:font-family="Calibri" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" 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%" loext:color-lum-mod="100%" loext:color-lum-off="0%" style:font-name="Calibri" fo:font-size="10pt" fo:language="de" fo:country="DE" style:letter-kerning="false" style:font-name-asian="Calibri1" style:font-size-asian="10pt" style:language-asian="de" style:country-asian="DE" style:font-name-complex="Times New Roman" style:font-size-complex="10pt" style:language-complex="ar" style:country-complex="SA"/>
+ </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.249cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Calibri" fo:font-size="10pt" fo:language="de" fo:country="DE" style:letter-kerning="false" style:font-name-asian="Calibri1" style:font-size-asian="10pt" style:language-asian="de" style:country-asian="DE" style:font-name-complex="Times New Roman" style:font-size-complex="10pt" style:language-complex="ar" style:country-complex="SA" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text">
+ <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.282cm" style:contextual-spacing="false" fo:line-height="108%" fo:text-align="start" style:justify-single-word="false" fo:orphans="2" fo:widows="2" style:writing-mode="lr-tb"/>
+ <style:text-properties fo:font-size="11pt" style:font-size-asian="11pt" style:language-asian="en" style:country-asian="US" style:font-size-complex="11pt"/>
+ </style:style>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ <style:default-page-layout>
+ <style:page-layout-properties style:layout-grid-standard-mode="true"/>
+ </style:default-page-layout>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="T1" style:family="text">
+ <style:text-properties fo:language="en" fo:country="IE"/>
+ </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="2.499cm" fo:margin-bottom="2cm" fo:margin-left="2.499cm" fo:margin-right="2.499cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="39" style:layout-grid-base-height="0.635cm" style:layout-grid-ruby-height="0cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:layout-grid-base-width="0.388cm" style:layout-grid-snap-to="true" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ <style:style style:name="dp1" style:family="drawing-page">
+ <style:drawing-page-properties draw:background-size="full"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/>
+ </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:p text:style-name="Standard"><field:fieldmark-start text:name="Bookmark1" field:type="vnd.oasis.opendocument.field.UNHANDLED"><field:param field:name="vnd.oasis.opendocument.field.code" field:value=""/></field:fieldmark-start><text:s/>QUOTE <text:s/>"foo </text:p>
+ <text:p text:style-name="Standard"><text:s/><field:fieldmark-start text:name="Bookmark" field:type="vnd.oasis.opendocument.field.UNHANDLED"><field:param field:name="vnd.oasis.opendocument.field.code" field:value=""/></field:fieldmark-start><text:s/>QUOTE <text:s/>"foo </text:p>
+ <text:p text:style-name="Standard"><text:s/>bar </text:p>
+ <text:p text:style-name="Standard">baz" <field:fieldmark-separator/>foo </text:p>
+ <text:p text:style-name="Standard"><text:s/>bar </text:p>
+ <text:p text:style-name="Standard">baz<field:fieldmark-end/></text:p>
+ <text:p text:style-name="Standard">bar </text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1">baz" </text:span><field:fieldmark-separator/><text:span text:style-name="T1">foo </text:span></text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1"><text:s/>foo </text:span></text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1"><text:s/>bar </text:span></text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1">baz</text:span></text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1">bar </text:span></text:p>
+ <text:p text:style-name="Standard"><text:span text:style-name="T1">baz</text:span><field:fieldmark-end/></text:p>
+ <text:p text:style-name="Standard"/>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index ebe5abb81804..fefc1fbda8ee 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -1041,6 +1041,7 @@ void Test::testNestedFieldmark()
pBatch->commit();
std::pair<OUString, OUString> const aFilterNames[] = {
+ {"writer8", "fieldmark_QUOTE_nest.fodt"},
{"Office Open XML Text", "fieldmark_QUOTE_nest.docx"},
{"Rich Text Format", "fieldmark_QUOTE_nest.rtf"},
};
@@ -1465,12 +1466,20 @@ void Test::testTextFormField()
// In the first paragraph we have an empty text form field with the placeholder spaces
const uno::Reference< text::XTextRange > xPara = getParagraph(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldStart"), getProperty<OUString>(getRun(xPara, 1), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldSeparator"), getProperty<OUString>(getRun(xPara, 2), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("Text"), getProperty<OUString>(getRun(xPara, 3), "TextPortionType"));
sal_Unicode vEnSpaces[5] = {8194, 8194, 8194, 8194, 8194};
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), xPara->getString());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), getRun(xPara, 3)->getString());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldEnd"), getProperty<OUString>(getRun(xPara, 4), "TextPortionType"));
// In the second paragraph we have a set text
const uno::Reference< text::XTextRange > xPara2 = getParagraph(2);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("xxxxx"), xPara2->getString());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldStart"), getProperty<OUString>(getRun(xPara2, 1), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldSeparator"), getProperty<OUString>(getRun(xPara2, 2), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("Text"), getProperty<OUString>(getRun(xPara2, 3), "TextPortionType"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("xxxxx"), getRun(xPara2, 3)->getString());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("TextFieldEnd"), getProperty<OUString>(getRun(xPara2, 4), "TextPortionType"));
}
}
diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx
index 57b2d1d9a5b2..09ccb69e6da4 100644
--- a/sw/source/core/inc/unobookmark.hxx
+++ b/sw/source/core/inc/unobookmark.hxx
@@ -61,7 +61,8 @@ protected:
/// @throws css::uno::RuntimeException
void attachToRangeEx(
const css::uno::Reference< css::text::XTextRange > & xTextRange,
- IDocumentMarkAccess::MarkType eType);
+ IDocumentMarkAccess::MarkType eType,
+ bool isFieldmarkSeparatorAtStart = false);
/// @throws css::lang::IllegalArgumentException
/// @throws css::uno::RuntimeException
virtual void attachToRange(
@@ -190,6 +191,7 @@ class SwXFieldmark final
{
::sw::mark::ICheckboxFieldmark* getCheckboxFieldmark();
bool const m_bReplacementObject;
+ bool m_isFieldmarkSeparatorAtStart = false;
css::uno::Reference<css::text::XTextRange>
GetCommand(::sw::mark::IFieldmark const& rMark);
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index a98956749713..456325d5f575 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -206,7 +206,8 @@ sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& r
void SwXBookmark::attachToRangeEx(
const uno::Reference< text::XTextRange > & xTextRange,
- IDocumentMarkAccess::MarkType eType)
+ IDocumentMarkAccess::MarkType eType,
+ bool const isFieldmarkSeparatorAtStart)
{
if (m_pImpl->m_pRegisteredBookmark)
{
@@ -247,7 +248,10 @@ void SwXBookmark::attachToRangeEx(
}
m_pImpl->registerInMark(*this,
m_pImpl->m_pDoc->getIDocumentMarkAccess()->makeMark(
- aPam, m_pImpl->m_sMarkName, eType, ::sw::mark::InsertMode::New));
+ aPam, m_pImpl->m_sMarkName, eType, ::sw::mark::InsertMode::New,
+ // note: aPam will be moved fwd by inserting start char, so sep
+ // will be directly following start
+ isFieldmarkSeparatorAtStart ? aPam.Start() : nullptr));
// #i81002#
// Check, if bookmark has been created.
// E.g., the creation of a cross-reference bookmark is suppress,
@@ -622,7 +626,8 @@ void SwXFieldmark::attachToRange( const uno::Reference < text::XTextRange >& xTe
{
attachToRangeEx( xTextRange,
- ( m_bReplacementObject ? IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK : IDocumentMarkAccess::MarkType::TEXT_FIELDMARK ) );
+ (m_bReplacementObject ? IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK : IDocumentMarkAccess::MarkType::TEXT_FIELDMARK),
+ m_isFieldmarkSeparatorAtStart);
}
OUString SwXFieldmark::getFieldType()
@@ -743,6 +748,14 @@ SwXFieldmark::setPropertyValue(const OUString& PropertyName,
pCheckboxFm->SetChecked( bChecked );
}
+ else if (PropertyName == "PrivateSeparatorAtStart")
+ {
+ bool isFieldmarkSeparatorAtStart{};
+ if (rValue >>= isFieldmarkSeparatorAtStart)
+ {
+ m_isFieldmarkSeparatorAtStart = isFieldmarkSeparatorAtStart;
+ }
+ }
// this doesn't support any SwXBookmark property
}
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index a996c4e9fb54..1606dbc68ab3 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3318,6 +3318,7 @@ namespace xmloff::token {
// enhanced fields
TOKEN( "fieldmark", XML_FIELDMARK ),
TOKEN( "fieldmark-start", XML_FIELDMARK_START ),
+ TOKEN( "fieldmark-separator", XML_FIELDMARK_SEPARATOR ),
TOKEN( "fieldmark-end", XML_FIELDMARK_END ),
TOKEN( "image-scale", XML_IMAGE_SCALE ),
diff --git a/xmloff/source/text/XMLTextMarkImportContext.cxx b/xmloff/source/text/XMLTextMarkImportContext.cxx
index 8e823d6c1757..4e42899e709c 100644
--- a/xmloff/source/text/XMLTextMarkImportContext.cxx
+++ b/xmloff/source/text/XMLTextMarkImportContext.cxx
@@ -35,6 +35,7 @@
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/text/ControlCharacter.hpp>
#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextRangeCompare.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/container/XNamed.hpp>
@@ -105,7 +106,7 @@ namespace {
enum lcl_MarkType { TypeReference, TypeReferenceStart, TypeReferenceEnd,
TypeBookmark, TypeBookmarkStart, TypeBookmarkEnd,
- TypeFieldmark, TypeFieldmarkStart, TypeFieldmarkEnd
+ TypeFieldmark, TypeFieldmarkStart, TypeFieldmarkSeparator, TypeFieldmarkEnd
};
}
@@ -120,6 +121,7 @@ SvXMLEnumMapEntry<lcl_MarkType> const lcl_aMarkTypeMap[] =
{ XML_BOOKMARK_END, TypeBookmarkEnd },
{ XML_FIELDMARK, TypeFieldmark },
{ XML_FIELDMARK_START, TypeFieldmarkStart },
+ { XML_FIELDMARK_SEPARATOR, TypeFieldmarkSeparator },
{ XML_FIELDMARK_END, TypeFieldmarkEnd },
{ XML_TOKEN_INVALID, lcl_MarkType(0) },
};
@@ -173,12 +175,12 @@ void XMLTextMarkImportContext::startFastElement( sal_Int32 nElement,
}
static auto InsertFieldmark(SvXMLImport & rImport,
- XMLTextImportHelper & rHelper, OUString const& rName) -> void
+ XMLTextImportHelper & rHelper, bool const isFieldmarkSeparatorMissing) -> void
{
assert(rHelper.hasCurrentFieldCtx()); // was set up in StartElement()
// fdo#86795 check if it's actually a checkbox first
- OUString const type(rHelper.getCurrentFieldType());
+ auto const [ name, type ] = rHelper.getCurrentFieldType();
OUString const fieldmarkTypeName = lcl_getFieldmarkName(type);
if (fieldmarkTypeName == ODF_FORMCHECKBOX ||
fieldmarkTypeName == ODF_FORMDROPDOWN)
@@ -187,9 +189,20 @@ static auto InsertFieldmark(SvXMLImport & rImport,
return;
}
+ uno::Reference<text::XTextRange> const xStartRange(rHelper.getCurrentFieldStart());
+ uno::Reference<text::XTextCursor> const xCursor(
+ rHelper.GetText()->createTextCursorByRange(xStartRange));
+ uno::Reference<text::XTextRangeCompare> const xCompare(rHelper.GetText(), uno::UNO_QUERY);
+ if (xCompare->compareRegionStarts(xStartRange, rHelper.GetCursorAsRange()) < 0)
+ {
+ SAL_WARN("xmloff.text", "invalid field mark positions");
+ assert(false);
+ }
+ xCursor->gotoRange(rHelper.GetCursorAsRange(), true);
+
Reference<XTextContent> const xContent = XMLTextMarkImportContext::CreateAndInsertMark(
- rImport, "com.sun.star.text.Fieldmark",
- rName, rHelper.GetCursorAsRange());
+ rImport, "com.sun.star.text.Fieldmark", name, xCursor,
+ OUString(), isFieldmarkSeparatorMissing);
if (!xContent.is())
return;
@@ -256,7 +269,7 @@ void XMLTextMarkImportContext::endFastElement(sal_Int32 nElement)
if (!SvXMLUnitConverter::convertEnum(nTmp, SvXMLImport::getNameFromToken(nElement), lcl_aMarkTypeMap))
return;
- if (m_sBookmarkName.isEmpty() && TypeFieldmarkEnd != nTmp)
+ if (m_sBookmarkName.isEmpty() && TypeFieldmarkEnd != nTmp && TypeFieldmarkSeparator != nTmp)
return;
switch (nTmp)
@@ -412,13 +425,21 @@ void XMLTextMarkImportContext::endFastElement(sal_Int32 nElement)
// else: no start found -> ignore!
break;
}
- case TypeFieldmarkStart: // no separator, so insert at start
+ case TypeFieldmarkStart:
+ {
+ break;
+ }
+ case TypeFieldmarkSeparator:
{
- InsertFieldmark(GetImport(), m_rHelper, m_sBookmarkName);
+ InsertFieldmark(GetImport(), m_rHelper, false);
break;
}
case TypeFieldmarkEnd:
{
+ if (!m_rHelper.hasCurrentFieldSeparator())
+ { // backward compat for old files without separator
+ InsertFieldmark(GetImport(), m_rHelper, true);
+ }
PopFieldmark(m_rHelper);
break;
}
@@ -446,7 +467,8 @@ Reference<XTextContent> XMLTextMarkImportContext::CreateAndInsertMark(
const OUString& sServiceName,
const OUString& sMarkName,
const Reference<XTextRange> & rRange,
- const OUString& i_rXmlId)
+ const OUString& i_rXmlId,
+ bool const isFieldmarkSeparatorMissing)
{
// create mark
const Reference<XMultiServiceFactory> xFactory(rImport.GetModel(),
@@ -478,6 +500,12 @@ Reference<XTextContent> XMLTextMarkImportContext::CreateAndInsertMark(
}
}
+ if (isFieldmarkSeparatorMissing)
+ {
+ uno::Reference<beans::XPropertySet> const xProps(xIfc, uno::UNO_QUERY_THROW);
+ xProps->setPropertyValue("PrivateSeparatorAtStart", uno::Any(true));
+ }
+
// cast to XTextContent and attach to document
const Reference<XTextContent> xTextContent(xIfc, UNO_QUERY);
if (xTextContent.is())
diff --git a/xmloff/source/text/XMLTextMarkImportContext.hxx b/xmloff/source/text/XMLTextMarkImportContext.hxx
index 407cddbadf7f..da05f524083e 100644
--- a/xmloff/source/text/XMLTextMarkImportContext.hxx
+++ b/xmloff/source/text/XMLTextMarkImportContext.hxx
@@ -96,7 +96,8 @@ public:
const OUString& sServiceName,
const OUString& sMarkName,
const css::uno::Reference<css::text::XTextRange> & rRange,
- const OUString& i_rXmlId = OUString());
+ const OUString& i_rXmlId = OUString(),
+ bool const isFieldmarkSeparatorMissing = false);
bool FindName(
const css::uno::Reference<css::xml::sax::XFastAttributeList> & xAttrList);
diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index 079e8df8d82d..f26ce21e66ab 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -166,7 +166,7 @@ struct XMLTextImportHelper::Impl
typedef ::std::pair< OUString, OUString> field_name_type_t;
typedef ::std::pair< OUString, OUString > field_param_t;
typedef ::std::vector< field_param_t > field_params_t;
- typedef ::std::tuple<field_name_type_t, field_params_t, uno::Reference<text::XFormField>> field_stack_item_t;
+ typedef ::std::tuple<field_name_type_t, field_params_t, uno::Reference<text::XFormField>, uno::Reference<text::XTextRange>> field_stack_item_t;
typedef ::std::stack< field_stack_item_t > field_stack_t;
field_stack_t m_FieldStack;
@@ -2105,7 +2105,7 @@ bool XMLTextImportHelper::FindAndRemoveBookmarkStartRange(
void XMLTextImportHelper::pushFieldCtx( const OUString& name, const OUString& type )
{
m_xImpl->m_FieldStack.push(Impl::field_stack_item_t(
- Impl::field_name_type_t(name, type), Impl::field_params_t(), uno::Reference<text::XFormField>{}));
+ Impl::field_name_type_t(name, type), Impl::field_params_t(), uno::Reference<text::XFormField>{}, GetCursor()->getStart()));
}
uno::Reference<text::XFormField>
@@ -2133,16 +2133,42 @@ void XMLTextImportHelper::addFieldParam( const OUString& name, const OUString& v
}
}
-OUString XMLTextImportHelper::getCurrentFieldType()
+::std::pair<OUString, OUString> XMLTextImportHelper::getCurrentFieldType() const
{
assert(!m_xImpl->m_FieldStack.empty());
if (!m_xImpl->m_FieldStack.empty())
{
- return std::get<0>(m_xImpl->m_FieldStack.top()).second;
+ return std::get<0>(m_xImpl->m_FieldStack.top());
}
else
{
- return OUString();
+ return {};
+ }
+}
+
+uno::Reference<text::XTextRange> XMLTextImportHelper::getCurrentFieldStart() const
+{
+ assert(!m_xImpl->m_FieldStack.empty());
+ if (!m_xImpl->m_FieldStack.empty())
+ {
+ return std::get<3>(m_xImpl->m_FieldStack.top());
+ }
+ else
+ {
+ return {};
+ }
+}
+
+bool XMLTextImportHelper::hasCurrentFieldSeparator() const
+{
+ assert(!m_xImpl->m_FieldStack.empty());
+ if (!m_xImpl->m_FieldStack.empty())
+ {
+ return std::get<2>(m_xImpl->m_FieldStack.top()).is();
+ }
+ else
+ {
+ return {};
}
}
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 5d9bd3768d01..63232f8b2822 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -181,6 +181,7 @@ constexpr OUStringLiteral gsVisitedCharStyleName(u"VisitedCharStyleName");
constexpr OUStringLiteral gsWidth(u"Width");
constexpr OUStringLiteral gsWidthType( u"WidthType" );
constexpr OUStringLiteral gsTextFieldStart( u"TextFieldStart" );
+constexpr OUStringLiteral gsTextFieldSep(u"TextFieldSeparator");
constexpr OUStringLiteral gsTextFieldEnd( u"TextFieldEnd" );
constexpr OUStringLiteral gsTextFieldStartEnd( u"TextFieldStartEnd" );
@@ -2284,6 +2285,19 @@ void XMLTextParagraphExport::exportTextRangeEnumeration(
}
}
}
+ else if (sType == gsTextFieldSep)
+ {
+ Reference<text::XFormField> const xFormField(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
+ if (!bAutoStyles)
+ {
+ if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
+ {
+ SvXMLElementExport aElem( GetExport(), !bAutoStyles,
+ XML_NAMESPACE_FIELD, XML_FIELDMARK_SEPARATOR,
+ false, false );
+ }
+ }
+ }
else if (sType == gsTextFieldEnd)
{
if (!bAutoStyles)
diff --git a/xmloff/source/text/txtparai.cxx b/xmloff/source/text/txtparai.cxx
index 3641d7e1af20..5a37d1e46894 100644
--- a/xmloff/source/text/txtparai.cxx
+++ b/xmloff/source/text/txtparai.cxx
@@ -1433,6 +1433,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > XMLImpSpanContext_Impl
case XML_ELEMENT(FIELD, XML_FIELDMARK):
case XML_ELEMENT(FIELD, XML_FIELDMARK_START):
+ case XML_ELEMENT(FIELD, XML_FIELDMARK_SEPARATOR):
case XML_ELEMENT(FIELD, XML_FIELDMARK_END):
pContext = new XMLTextMarkImportContext(rImport, *rImport.GetTextImport(),
rHints.GetCrossRefHeadingBookmark());
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 849802878614..568122e0f582 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3093,6 +3093,7 @@ use-zero
ignore
fieldmark
fieldmark-start
+fieldmark-separator
fieldmark-end
image-scale
isotropic