sw/qa/extras/globalfilter/globalfilter.cxx | 8 ++-- sw/source/core/crsr/bookmrk.cxx | 29 ++++++++++------ sw/source/core/doc/docbm.cxx | 5 ++ sw/source/core/inc/UndoBookmark.hxx | 28 +++++++++++++++ sw/source/core/inc/rolbck.hxx | 8 +++- sw/source/core/undo/rolbck.cxx | 51 ++++++++++++++++------------- sw/source/core/undo/unbkmk.cxx | 36 ++++++++++++++++++++ sw/source/uibase/shells/textfld.cxx | 10 +++-- 8 files changed, 132 insertions(+), 43 deletions(-)
New commits: commit 12385f9e79e15b215c1d398b4bfb212ef1b23fb3 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 11 14:50:57 2019 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Wed Oct 23 13:01:11 2019 +0200 sw: fieldmark insert/delete Undo SwHistoryTextFieldmark implementation doesn't work that well with its hardcoded +5 etc. so reimplement that storing all 3 positions. Add Undo classes for deletion as well, and use them automatically when deleteMark() is called with Undo enabled. Change-Id: I45a73080b08bde9e046525892c101aa2d622269e Reviewed-on: https://gerrit.libreoffice.org/80627 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index 713d36d2d63d..7e514b7e18da 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -511,6 +511,12 @@ namespace sw { namespace mark void TextFieldmark::ReleaseDoc(SwDoc* const pDoc) { + IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo()); + if (rIDUR.DoesUndo()) + { + rIDUR.AppendUndo(std::make_unique<SwUndoDelTextFieldmark>(*this)); + } + ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND); } @@ -540,6 +546,12 @@ namespace sw { namespace mark void NonTextFieldmark::ReleaseDoc(SwDoc* const pDoc) { + IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo()); + if (rIDUR.DoesUndo()) + { + rIDUR.AppendUndo(std::make_unique<SwUndoDelNoTextFieldmark>(*this)); + } + ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT); } @@ -656,6 +668,13 @@ namespace sw { namespace mark void DateFieldmark::ReleaseDoc(SwDoc* const pDoc) { + IDocumentUndoRedo & rIDUR(pDoc->GetIDocumentUndoRedo()); + if (rIDUR.DoesUndo()) + { + // TODO does this need a 3rd Undo class? + rIDUR.AppendUndo(std::make_unique<SwUndoDelTextFieldmark>(*this)); + } + ::sw::UndoGuard const ug(rIDUR); // prevent SwUndoDeletes lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND); } diff --git a/sw/source/core/inc/UndoBookmark.hxx b/sw/source/core/inc/UndoBookmark.hxx index 3e2017d0721d..ebaac8cd19e7 100644 --- a/sw/source/core/inc/UndoBookmark.hxx +++ b/sw/source/core/inc/UndoBookmark.hxx @@ -111,6 +111,20 @@ public: virtual void RedoImpl( ::sw::UndoRedoContext & ) override; }; +/// Handling undo / redo of checkbox and drop-down form field deletion +class SwUndoDelNoTextFieldmark : public SwUndo +{ +private: + const std::unique_ptr<SwHistoryNoTextFieldmark> m_pHistoryNoTextFieldmark; + +public: + SwUndoDelNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark); + ~SwUndoDelNoTextFieldmark(); + + virtual void UndoImpl( ::sw::UndoRedoContext & ) override; + virtual void RedoImpl( ::sw::UndoRedoContext & ) override; +}; + /// Handling undo / redo of text form field insertion class SwUndoInsTextFieldmark : public SwUndo { @@ -124,6 +138,20 @@ public: virtual void RedoImpl( ::sw::UndoRedoContext & ) override; }; +/// Handling undo / redo of text form field deletion +class SwUndoDelTextFieldmark : public SwUndo +{ +private: + const std::unique_ptr<SwHistoryTextFieldmark> m_pHistoryTextFieldmark; + +public: + SwUndoDelTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark); + ~SwUndoDelTextFieldmark(); + + virtual void UndoImpl( ::sw::UndoRedoContext & ) override; + virtual void RedoImpl( ::sw::UndoRedoContext & ) override; +}; + #endif // INCLUDED_SW_SOURCE_CORE_INC_UNDOBOOKMARK_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/inc/rolbck.hxx b/sw/source/core/inc/rolbck.hxx index 6fb81943af4d..91e9d85574b1 100644 --- a/sw/source/core/inc/rolbck.hxx +++ b/sw/source/core/inc/rolbck.hxx @@ -288,8 +288,12 @@ class SwHistoryTextFieldmark : public SwHistoryHint private: const OUString m_sName; const OUString m_sType; - const sal_uLong m_nNode; - const sal_Int32 m_nContent; + const sal_uLong m_nStartNode; + const sal_Int32 m_nStartContent; + const sal_uLong m_nEndNode; + const sal_Int32 m_nEndContent; + /*const*/ sal_uLong m_nSepNode; + /*const*/ sal_Int32 m_nSepContent; }; class SwHistorySetAttrSet : public SwHistoryHint diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx index d500679eefee..8a2c027b93f5 100644 --- a/sw/source/core/undo/rolbck.cxx +++ b/sw/source/core/undo/rolbck.cxx @@ -722,9 +722,14 @@ SwHistoryTextFieldmark::SwHistoryTextFieldmark(const ::sw::mark::IFieldmark& rFi : SwHistoryHint(HSTRY_TEXTFIELDMARK) , m_sName(rFieldMark.GetName()) , m_sType(rFieldMark.GetFieldname()) - , m_nNode(rFieldMark.GetMarkPos().nNode.GetIndex()) - , m_nContent(rFieldMark.GetMarkPos().nContent.GetIndex()) + , m_nStartNode(rFieldMark.GetMarkStart().nNode.GetIndex()) + , m_nStartContent(rFieldMark.GetMarkStart().nContent.GetIndex()) + , m_nEndNode(rFieldMark.GetMarkEnd().nNode.GetIndex()) + , m_nEndContent(rFieldMark.GetMarkEnd().nContent.GetIndex()) { + SwPosition const sepPos(sw::mark::FindFieldSep(rFieldMark)); + m_nSepNode = sepPos.nNode.GetIndex(); + m_nSepContent = sepPos.nContent.GetIndex(); } void SwHistoryTextFieldmark::SetInDoc(SwDoc* pDoc, bool) @@ -732,19 +737,23 @@ void SwHistoryTextFieldmark::SetInDoc(SwDoc* pDoc, bool) ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); SwNodes& rNds = pDoc->GetNodes(); - std::unique_ptr<SwPaM> pPam; - const SwContentNode* pContentNd = rNds[m_nNode]->GetContentNode(); - if(pContentNd) - pPam.reset(new SwPaM(*pContentNd, m_nContent)); + assert(rNds[m_nStartNode]->IsContentNode()); + assert(rNds[m_nEndNode]->IsContentNode()); + assert(rNds[m_nSepNode]->IsContentNode()); - if (pPam) - { - IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess(); - SwPaM aFieldPam(pPam->GetPoint()->nNode, pPam->GetPoint()->nContent.GetIndex(), - pPam->GetPoint()->nNode, pPam->GetPoint()->nContent.GetIndex() + 5); - pMarksAccess->makeFieldBookmark(aFieldPam, m_sName, m_sType); - } + SwPaM const pam(*rNds[m_nStartNode]->GetContentNode(), m_nStartContent, + *rNds[m_nEndNode]->GetContentNode(), + m_nStartNode == m_nEndNode + ? (m_nEndContent - 2) + : m_nSepNode == m_nEndNode + ? (m_nEndContent - 1) + : m_nEndContent); + SwPosition const sepPos(*rNds[m_nSepNode]->GetContentNode(), + m_nStartNode == m_nSepNode ? (m_nSepContent - 1) : m_nSepContent); + + IDocumentMarkAccess & rMarksAccess(*pDoc->getIDocumentMarkAccess()); + rMarksAccess.makeFieldBookmark(pam, m_sName, m_sType, &sepPos); } void SwHistoryTextFieldmark::ResetInDoc(SwDoc* pDoc) @@ -752,17 +761,15 @@ void SwHistoryTextFieldmark::ResetInDoc(SwDoc* pDoc) ::sw::UndoGuard const undoGuard(pDoc->GetIDocumentUndoRedo()); SwNodes& rNds = pDoc->GetNodes(); - std::unique_ptr<SwPaM> pPam; - const SwContentNode* pContentNd = rNds[m_nNode]->GetContentNode(); - if(pContentNd) - pPam.reset(new SwPaM(*pContentNd, m_nContent)); + assert(rNds[m_nStartNode]->IsContentNode()); + assert(rNds[m_nEndNode]->IsContentNode()); + assert(rNds[m_nSepNode]->IsContentNode()); - if (pPam) - { - IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); - pMarkAccess->deleteFieldmarkAt(*pPam->GetPoint()); - } + SwPosition const pos(*rNds[m_nStartNode]->GetContentNode(), m_nStartContent); + + IDocumentMarkAccess & rMarksAccess(*pDoc->getIDocumentMarkAccess()); + rMarksAccess.deleteFieldmarkAt(pos); } SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet, diff --git a/sw/source/core/undo/unbkmk.cxx b/sw/source/core/undo/unbkmk.cxx index 310113ff4ed7..6cc805d1518d 100644 --- a/sw/source/core/undo/unbkmk.cxx +++ b/sw/source/core/undo/unbkmk.cxx @@ -164,6 +164,24 @@ void SwUndoInsNoTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext) m_pHistoryNoTextFieldmark->SetInDoc(&rContext.GetDoc(), false); } +SwUndoDelNoTextFieldmark::SwUndoDelNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark) + : SwUndo(SwUndoId::DELETE, rFieldmark.GetMarkPos().GetDoc()) + , m_pHistoryNoTextFieldmark(new SwHistoryNoTextFieldmark(rFieldmark)) +{ +} + +SwUndoDelNoTextFieldmark::~SwUndoDelNoTextFieldmark() = default; + +void SwUndoDelNoTextFieldmark::UndoImpl(::sw::UndoRedoContext & rContext) +{ + m_pHistoryNoTextFieldmark->SetInDoc(&rContext.GetDoc(), false); +} + +void SwUndoDelNoTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext) +{ + m_pHistoryNoTextFieldmark->ResetInDoc(&rContext.GetDoc()); +} + SwUndoInsTextFieldmark::SwUndoInsTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark) : SwUndo(SwUndoId::INSERT, rFieldmark.GetMarkPos().GetDoc()) , m_pHistoryTextFieldmark(new SwHistoryTextFieldmark(rFieldmark)) @@ -180,4 +198,22 @@ void SwUndoInsTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext) m_pHistoryTextFieldmark->SetInDoc(&rContext.GetDoc(), false); } +SwUndoDelTextFieldmark::SwUndoDelTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark) + : SwUndo(SwUndoId::DELETE, rFieldmark.GetMarkPos().GetDoc()) + , m_pHistoryTextFieldmark(new SwHistoryTextFieldmark(rFieldmark)) +{ +} + +SwUndoDelTextFieldmark::~SwUndoDelTextFieldmark() = default; + +void SwUndoDelTextFieldmark::UndoImpl(::sw::UndoRedoContext & rContext) +{ + m_pHistoryTextFieldmark->SetInDoc(&rContext.GetDoc(), false); +} + +void SwUndoDelTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext) +{ + m_pHistoryTextFieldmark->ResetInDoc(&rContext.GetDoc()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit bc5e4104e281b89c08df102851e5693f35772c40 Author: Michael Stahl <michael.st...@cib.de> AuthorDate: Fri Oct 11 14:57:04 2019 +0200 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Wed Oct 23 13:00:51 2019 +0200 sw: DateFieldmark separator position: hack to put it at the start DateFieldmark isn't created for an actual field with a command but for a SDT (Date Picker Content Control), so it's somewhat pointless to insert a separator for it in the first place; but better have an invariant that every pair of FIELDSTART/FIELDEND has a FIELDSEP. TODO: maybe add another pair of distinct START/END for this thing. Change-Id: I37301b578c668ecbf9408a48c227db5991c33f9e Reviewed-on: https://gerrit.libreoffice.org/80675 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 4c47c284fc59..a97b204aff71 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -1399,10 +1399,10 @@ void Test::testDateFormFieldCharacterFormatting() CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(11), pFieldmark->GetMarkEnd().nContent.GetIndex()); // We have one date field, first half of the field has bold character weight and second part has red character color - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(1), 2), "CharWeight")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(COL_AUTO), getProperty<sal_Int32>(getRun(getParagraph(1), 2), "CharColor")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(getRun(getParagraph(1), 3), "CharWeight")); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0xff0000), getProperty<sal_Int32>(getRun(getParagraph(1), 3), "CharColor")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(1), 3), "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(COL_AUTO), getProperty<sal_Int32>(getRun(getParagraph(1), 3), "CharColor")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(getRun(getParagraph(1), 4), "CharWeight")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0xff0000), getProperty<sal_Int32>(getRun(getParagraph(1), 4), "CharColor")); } } diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index ba43b2158bd4..713d36d2d63d 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -704,13 +704,8 @@ namespace sw { namespace mark { const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode(); SwPosition const sepPos(sw::mark::FindFieldSep(*this)); -#if 0 const sal_Int32 nStart(sepPos.nContent.GetIndex()); const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex()); -#else - const sal_Int32 nStart(GetMarkStart().nContent.GetIndex()); - const sal_Int32 nEnd (sepPos.nContent.GetIndex() + 1); -#endif OUString sContent; if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() && @@ -726,13 +721,8 @@ namespace sw { namespace mark const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode(); SwPosition const sepPos(sw::mark::FindFieldSep(*this)); -#if 0 const sal_Int32 nStart(sepPos.nContent.GetIndex()); const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex()); -#else - const sal_Int32 nStart(GetMarkStart().nContent.GetIndex()); - const sal_Int32 nEnd (sepPos.nContent.GetIndex() + 1); -#endif if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() && nEnd > nStart + 2) diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 4f13bea2d79f..88a6019251b4 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1341,7 +1341,10 @@ namespace sw { namespace mark SwPosition aPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent); SwPaM aNewPaM(pFieldmark->GetMarkStart(), pFieldmark->GetMarkEnd()); deleteFieldmarkAt(aPos); - return makeFieldBookmark(aNewPaM, sName, rNewType); + // HACK: hard-code the separator position here at the start because + // writerfilter put it in the wrong place (at the end) on attach() + SwPosition const sepPos(*aNewPaM.Start()); + return makeFieldBookmark(aNewPaM, sName, rNewType, &sepPos); } return nullptr; } diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index ea78347f73a9..c65d5d65da6a 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -691,9 +691,10 @@ FIELD_INSERT: if(bSuccess) { IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); - SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()-5, + SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - ODF_FORMFIELD_DEFAULT_LENGTH, pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); - pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT); + pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT, + aFieldPam.Start()); } } @@ -744,9 +745,10 @@ FIELD_INSERT: if(bSuccess) { IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); - SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()-5, + SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - ODF_FORMFIELD_DEFAULT_LENGTH, pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); - sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE); + sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE, + aFieldPam.Start()); // Use a default date format and language sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldBM->GetParameters(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits