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

Reply via email to