[Libreoffice-commits] core.git: 2 commits - sw/inc sw/qa sw/source writerfilter/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Wed Oct 23 11:03:24 UTC 2019
sw/inc/IDocumentMarkAccess.hxx | 2 +
sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 2 -
sw/source/core/doc/docbm.cxx | 15 +++++++++
sw/source/uibase/wrtsh/delete.cxx | 10 +++++-
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 35 ++++++++++++++++++----
5 files changed, 55 insertions(+), 9 deletions(-)
New commits:
commit 6851182cb61a70d3ebd6ee098e8ba5f23582b352
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Oct 11 14:06:25 2019 +0200
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Wed Oct 23 13:02:14 2019 +0200
sw: SwWrtShell: delete field command when deleting the field
Change-Id: I6dbb7a36bdca103d6e9e72a5b5b48ffc135080a1
Reviewed-on: https://gerrit.libreoffice.org/80676
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 1e2db2436a61..a076a6dada66 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -343,6 +343,8 @@ class IDocumentMarkAccess
static SW_DLLPUBLIC OUString GetCrossRefHeadingBookmarkNamePrefix();
static SW_DLLPUBLIC bool IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPaM );
+ static void DeleteFieldmarkCommand(::sw::mark::IFieldmark const& rMark);
+
protected:
virtual ~IDocumentMarkAccess() {};
};
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 88a6019251b4..4f94baab5c90 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -530,6 +530,17 @@ bool IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( const SwPaM& rPa
rPaM.End()->nContent.GetIndex() == rPaM.End()->nNode.GetNode().GetTextNode()->Len() ) );
}
+void IDocumentMarkAccess::DeleteFieldmarkCommand(::sw::mark::IFieldmark const& rMark)
+{
+ if (GetType(rMark) != MarkType::TEXT_FIELDMARK)
+ {
+ return; // TODO FORMDATE has no command?
+ }
+ SwPaM pam(sw::mark::FindFieldSep(rMark), rMark.GetMarkStart());
+ ++pam.GetPoint()->nContent; // skip CH_TXT_ATR_FIELDSTART
+ pam.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(pam);
+}
+
namespace sw { namespace mark
{
MarkManager::MarkManager(SwDoc& rDoc)
@@ -1104,6 +1115,10 @@ namespace sw { namespace mark
}
virtual ~LazyFieldmarkDeleter() override
{
+ // note: because of the call chain from SwUndoDelete, the field
+ // command *cannot* be deleted here as it would create a separate
+ // SwUndoDelete that's interleaved with the SwHistory of the outer
+ // one - only delete the CH_TXT_ATR_FIELD*!
m_pFieldmark->ReleaseDoc(m_pDoc);
}
};
diff --git a/sw/source/uibase/wrtsh/delete.cxx b/sw/source/uibase/wrtsh/delete.cxx
index cbb3fad91b69..4a2420ad7b84 100644
--- a/sw/source/uibase/wrtsh/delete.cxx
+++ b/sw/source/uibase/wrtsh/delete.cxx
@@ -239,10 +239,13 @@ bool SwWrtShell::DelLeft()
const SwPosition* pCurPos = GetCursor()->GetPoint();
SwPosition aPrevChar(*pCurPos);
--aPrevChar.nContent;
- sw::mark::IFieldmark* pFm = getIDocumentMarkAccess()->getFieldmarkFor(aPrevChar);
+ sw::mark::IFieldmark* pFm = getIDocumentMarkAccess()->getFieldmarkAt(aPrevChar);
if (pFm && pFm->GetMarkEnd() == *pCurPos)
{
+ mxDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
+ IDocumentMarkAccess::DeleteFieldmarkCommand(*pFm);
getIDocumentMarkAccess()->deleteMark(pFm);
+ mxDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
return true;
}
@@ -375,10 +378,13 @@ bool SwWrtShell::DelRight()
{
// If we are just ahead of a fieldmark, then remove it completely
- sw::mark::IFieldmark* pFm = GetCurrentFieldmark();
+ sw::mark::IFieldmark *const pFm = getIDocumentMarkAccess()->getFieldmarkAt(*GetCursor()->GetPoint());
if (pFm && pFm->GetMarkStart() == *GetCursor()->GetPoint())
{
+ mxDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
+ IDocumentMarkAccess::DeleteFieldmarkCommand(*pFm);
getIDocumentMarkAccess()->deleteMark(pFm);
+ mxDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
bRet = true;
break;
}
commit f610f9b611fe9f206b872ed06f7e859d688385fc
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Oct 2 17:15:32 2019 +0200
Commit: Michael Stahl <michael.stahl at cib.de>
CommitDate: Wed Oct 23 13:01:53 2019 +0200
writerfilter: import nested generic fields from RTF
* for m_bStartGenericField, push new insert position onto the stack in
DomainMapper_Impl::CloseFieldCommand(), not in
DomainMapper_Impl::appendTextPortion()
* how is the field result inserted into the field, instead of after it?
- it doesn't seem possible to move the insertion of the field mark to
PopFieldContext(), as there's no way to pass 3 positions to
attach(), and exposing a writable property for the position(s)
is a bad idea
- finishParagraph() calls AppendTextNode(), which happily ignores a
content index on the given XTextRange
- so temporarily insert a paragraph break, override the insert
position, and join the paragraphs in PopFieldContext()
Change-Id: Ie49084f6ea6451e7d7f9b613cedce326de9a54f1
Reviewed-on: https://gerrit.libreoffice.org/80075
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index e269a3bfba6e..3996c634ab8f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -537,7 +537,7 @@ DECLARE_OOXMLEXPORT_TEST(testSdtDateDuplicate, "sdt-date-duplicate.docx")
DECLARE_OOXMLEXPORT_TEST(testFdo81492, "fdo81492.docx")
{
if (xmlDocPtr pXmlDoc = parseExport())
- assertXPathContent(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[9]/w:instrText", "ADDIN EN.CITE.DATA");
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[7]/w:instrText", "ADDIN EN.CITE.DATA");
}
DECLARE_OOXMLEXPORT_TEST(testEditTime, "fdo81341.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index b9c053700574..b2cb490f221a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1779,7 +1779,10 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const Proper
m_bTextInserted = true;
xTOCTextCursor->gotoRange(xTextRange->getEnd(), true);
mxTOCTextCursor = xTOCTextCursor;
- m_aTextAppendStack.push(TextAppendContext(xTextAppend, xTOCTextCursor));
+ if (!m_bStartGenericField)
+ {
+ m_aTextAppendStack.push(TextAppendContext(xTextAppend, xTOCTextCursor));
+ }
}
}
else
@@ -5029,12 +5032,27 @@ void DomainMapper_Impl::CloseFieldCommand()
const uno::Reference<text::XTextContent> xTextContent(xFieldInterface, uno::UNO_QUERY_THROW);
uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend;
uno::Reference< text::XTextCursor > xCrsr = xTextAppend->createTextCursorByRange(pContext->GetStartRange());
- if (xTextContent.is())
+ if (m_aTextAppendStack.top().xInsertPosition.is())
+ {
+ xCrsr->gotoRange(m_aTextAppendStack.top().xInsertPosition, true);
+ }
+ else
{
- xTextAppend->insertTextContent(xCrsr,xTextContent, true);
+ xCrsr->gotoEnd(true);
}
- uno::Reference<uno::XInterface> xContent(xTextContent);
- uno::Reference< text::XFormField> xFormField(xContent, uno::UNO_QUERY);
+ xTextAppend->insertTextContent(xCrsr, xTextContent, true);
+ // problem: the fieldmark must be inserted here, because
+ // attach() takes 2 positions, not 3!
+ // FAIL: AppendTextNode() ignores the content index!
+ // plan B: insert a spurious paragraph break now and join
+ // it in PopFieldContext()!
+ xCrsr->gotoRange(xTextContent->getAnchor()->getEnd(), false);
+ xCrsr->goLeft(1, false); // skip CH_TXT_ATR_FIELDEND
+ xTextAppend->insertControlCharacter(xCrsr, text::ControlCharacter::PARAGRAPH_BREAK, false);
+ xCrsr->goLeft(1, false); // back to previous paragraph
+ m_aTextAppendStack.push(TextAppendContext(xTextAppend, xCrsr));
+
+ uno::Reference<text::XFormField> xFormField(xTextContent, uno::UNO_QUERY);
xFormField->setFieldType(aCode);
m_bStartGenericField = true;
pContext->SetFormField( xFormField );
@@ -5396,9 +5414,14 @@ void DomainMapper_Impl::PopFieldContext()
else if(m_bStartGenericField)
{
m_bStartGenericField = false;
+ xCrsr->gotoRange(m_aTextAppendStack.top().xInsertPosition, false);
+ xCrsr->goRight(1, true);
+ xCrsr->setString(OUString()); // undo SplitNode from CloseFieldCommand()
+ // note: paragraph properties will be overwritten
+ // by finishParagraph() anyway so ignore here
+ m_aTextAppendStack.pop();
if(m_bTextInserted)
{
- m_aTextAppendStack.pop();
m_bTextInserted = false;
}
}
More information about the Libreoffice-commits
mailing list