[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - sw/inc sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Mar 18 09:09:10 UTC 2019


 sw/inc/IDocumentMarkAccess.hxx      |    2 
 sw/inc/strings.hrc                  |    1 
 sw/inc/swundo.hxx                   |    4 +
 sw/source/core/doc/docbm.cxx        |   34 +++++++++++++
 sw/source/core/inc/MarkManager.hxx  |    2 
 sw/source/core/inc/UndoBookmark.hxx |   27 ++++++++++
 sw/source/core/inc/rolbck.hxx       |   29 +++++++++++
 sw/source/core/undo/rolbck.cxx      |   90 ++++++++++++++++++++++++++++++++++++
 sw/source/core/undo/unbkmk.cxx      |   32 ++++++++++++
 sw/source/core/undo/undobj.cxx      |    3 +
 sw/source/uibase/shells/textfld.cxx |   16 ++++++
 11 files changed, 239 insertions(+), 1 deletion(-)

New commits:
commit 788c25b68fc48275eebd13e94f3bf81d5eb8c7bb
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Feb 21 13:38:33 2019 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Mar 18 10:08:47 2019 +0100

    MSForms: Implement undo / redo for insertion of legacy form fields
    
    Need to handle undo / redo explicitely for form fields, because
    there is no a general working undo / redo mechanism for fieldmarks.
    During the insertion of the fieldmark, text insertion also happens which
    generates an interfering undo action, so we need to disable undoing
    temporary.
    Also need to invalidta SID_UNDO slot to make the undo toolbar item updated
    after we insert a form field.
    
    Reviewed-on: https://gerrit.libreoffice.org/68956
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 55d6be75732d1bb0067bba9496c74ef30be9a3ec)
    
    Change-Id: I358c2704cb30212a38f8a998888a36f72fa404e5
    Reviewed-on: https://gerrit.libreoffice.org/69190
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>

diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 3fb7090e5067..823326e2b8ac 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -254,6 +254,8 @@ class IDocumentMarkAccess
         virtual ::sw::mark::IFieldmark* getDropDownFor(const SwPosition& pos) const=0;
         virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0;
 
+        virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
+
         // Annotation Marks
         virtual const_iterator_t getAnnotationMarksBegin() const = 0;
         virtual const_iterator_t getAnnotationMarksEnd() const = 0;
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index c0adc4b549ca..e0edcb4ab7c0 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -522,6 +522,7 @@
 #define STR_UNDO_TBLSTYLE_DELETE                NC_("STR_UNDO_TBLSTYLE_DELETE", "Delete table style: $1")
 #define STR_UNDO_TBLSTYLE_UPDATE                NC_("STR_UNDO_TBLSTYLE_UPDATE", "Update table style: $1")
 #define STR_UNDO_TABLE_DELETE                   NC_("STR_UNDO_TABLE_DELETE", "Delete table")
+#define STR_UNDO_INSERT_FORM_FIELD              NC_("STR_UNDO_INSERT_FORM_FIELD", "Insert form field")
 
 #define STR_ACCESS_DOC_NAME                     NC_("STR_ACCESS_DOC_NAME", "Document view")
 #define STR_ACCESS_DOC_DESC                     NC_("STR_ACCESS_DOC_DESC", "Document view")
diff --git a/sw/inc/swundo.hxx b/sw/inc/swundo.hxx
index c393554f0614..90fa6c51d055 100644
--- a/sw/inc/swundo.hxx
+++ b/sw/inc/swundo.hxx
@@ -162,7 +162,9 @@ enum class SwUndoId
     UI_DELETE_PAGE_BREAK,              // 131
     UI_TEXT_CORRECTION,                // 132
     UI_TABLE_DELETE,                   // 133
-    CONFLICT                           // 134
+    CONFLICT,                          // 134
+
+    INSERT_FORM_FIELD                  // 135
 };
 
 OUString GetUndoComment(SwUndoId eId);
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index dc9ebb40ed72..ccc3d5382ffb 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -491,6 +491,10 @@ namespace sw { namespace mark
         const OUString& rName,
         const OUString& rType )
     {
+        // Disable undo, because we handle it using SwUndoInsTextFieldmark
+        bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
+        m_pDoc->GetIDocumentUndoRedo().DoUndo(false);
+
         sw::mark::IMark* pMark = makeMark( rPaM, rName,
                 IDocumentMarkAccess::MarkType::TEXT_FIELDMARK,
                 sw::mark::InsertMode::New);
@@ -498,6 +502,13 @@ namespace sw { namespace mark
         if (pFieldMark)
             pFieldMark->SetFieldname( rType );
 
+        if (bUndoIsEnabled)
+        {
+            m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoIsEnabled);
+            SwUndo* pUndo = new SwUndoInsTextFieldmark(*pFieldMark);
+            m_pDoc->GetIDocumentUndoRedo().AppendUndo(pUndo);
+        }
+
         return pFieldMark;
     }
 
@@ -506,6 +517,10 @@ namespace sw { namespace mark
         const OUString& rName,
         const OUString& rType)
     {
+        // Disable undo, because we handle it using SwUndoInsNoTextFieldmark
+        bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
+        m_pDoc->GetIDocumentUndoRedo().DoUndo(false);
+
         bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
         m_pDoc->getIDocumentState().SetEnableSetModified(false);
 
@@ -516,6 +531,13 @@ namespace sw { namespace mark
         if (pFieldMark)
             pFieldMark->SetFieldname( rType );
 
+        if (bUndoIsEnabled)
+        {
+            m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoIsEnabled);
+            SwUndo* pUndo = new SwUndoInsNoTextFieldmark(*pFieldMark);
+            m_pDoc->GetIDocumentUndoRedo().AppendUndo(pUndo);
+        }
+
         m_pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified);
         m_pDoc->getIDocumentState().SetModified();
 
@@ -1051,6 +1073,18 @@ namespace sw { namespace mark
         return dynamic_cast<IFieldmark*>(pFieldmark->get());
     }
 
+    void MarkManager::deleteFieldmarkAt(const SwPosition& rPos)
+    {
+        const_iterator_t pFieldmark = find_if(
+            m_vFieldmarks.begin(),
+            m_vFieldmarks.end(),
+            [&rPos] (pMark_t const& rpMark) { return rpMark->IsCoveringPosition(rPos); } );
+        if(pFieldmark == m_vFieldmarks.end()) return;
+
+        deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
+    }
+
+
     IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
     {
         IFieldmark *pMark = getFieldmarkFor(rPos);
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index a12657ef2469..7a3612bb6131 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -85,6 +85,8 @@ namespace sw {
             virtual ::sw::mark::IFieldmark* getDropDownFor(const SwPosition &rPos) const override;
             virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override;
 
+            virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
+
             void dumpAsXml(struct _xmlTextWriter* pWriter) const;
 
             // Annotation Marks
diff --git a/sw/source/core/inc/UndoBookmark.hxx b/sw/source/core/inc/UndoBookmark.hxx
index eb32662c92d8..7b9dd4fc68e5 100644
--- a/sw/source/core/inc/UndoBookmark.hxx
+++ b/sw/source/core/inc/UndoBookmark.hxx
@@ -24,10 +24,13 @@
 #include <undobj.hxx>
 
 class SwHistoryBookmark;
+class SwHistoryNoTextFieldmark;
+class SwHistoryTextFieldmark;
 
 namespace sw {
     namespace mark {
         class IMark;
+        class IFieldmark;
     }
 }
 
@@ -95,6 +98,30 @@ private:
     virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
 };
 
+class SwUndoInsNoTextFieldmark : public SwUndo
+{
+private:
+    const std::unique_ptr<SwHistoryNoTextFieldmark> m_pHistoryNoTextFieldmark;
+
+public:
+    SwUndoInsNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark);
+
+    virtual void UndoImpl( ::sw::UndoRedoContext & ) override;
+    virtual void RedoImpl( ::sw::UndoRedoContext & ) override;
+};
+
+class SwUndoInsTextFieldmark : public SwUndo
+{
+private:
+    const std::unique_ptr<SwHistoryTextFieldmark> m_pHistoryTextFieldmark;
+
+public:
+    SwUndoInsTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark);
+
+    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 88b629cfed5d..d7985fde8592 100644
--- a/sw/source/core/inc/rolbck.hxx
+++ b/sw/source/core/inc/rolbck.hxx
@@ -71,6 +71,8 @@ enum HISTORY_HINT {
     HSTRY_CHGFLYANCHOR,
     HSTRY_CHGFLYCHAIN,
     HSTRY_CHGCHARFMT,
+    HSTRY_NOTEXTFIELDMARK,
+    HSTRY_TEXTFIELDMARK,
 };
 
 class SwHistoryHint
@@ -259,6 +261,33 @@ class SwHistoryBookmark : public SwHistoryHint
         std::shared_ptr< ::sfx2::MetadatableUndo > m_pMetadataUndo;
 };
 
+class SwHistoryNoTextFieldmark : public SwHistoryHint
+{
+    public:
+        SwHistoryNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldMark);
+        virtual void SetInDoc(SwDoc* pDoc, bool) override;
+        void ResetInDoc(SwDoc* pDoc);
+
+    private:
+        const OUString m_sType;
+        const sal_uLong m_nNode;
+        const sal_Int32 m_nContent;
+};
+
+class SwHistoryTextFieldmark : public SwHistoryHint
+{
+    public:
+        SwHistoryTextFieldmark(const ::sw::mark::IFieldmark& rFieldMark);
+        virtual void SetInDoc(SwDoc* pDoc, bool) override;
+        void ResetInDoc(SwDoc* pDoc);
+
+    private:
+        const OUString m_sName;
+        const OUString m_sType;
+        const sal_uLong m_nNode;
+        const sal_Int32 m_nContent;
+};
+
 class SwHistorySetAttrSet : public SwHistoryHint
 {
     SfxItemSet m_OldSet;
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index 6459a46f692e..e1e03f92ddb2 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -673,6 +673,96 @@ bool SwHistoryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
         && m_aName == rBkmk.GetName();
 }
 
+SwHistoryNoTextFieldmark::SwHistoryNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldMark)
+    : SwHistoryHint(HSTRY_NOTEXTFIELDMARK)
+    , m_sType(rFieldMark.GetFieldname())
+    , m_nNode(rFieldMark.GetMarkPos().nNode.GetIndex())
+    , m_nContent(rFieldMark.GetMarkPos().nContent.GetIndex())
+{
+}
+
+void SwHistoryNoTextFieldmark::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));
+
+    if (pPam)
+    {
+        IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+        pMarkAccess->makeNoTextFieldBookmark(*pPam, OUString(), m_sType);
+    }
+}
+
+void SwHistoryNoTextFieldmark::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-1));
+
+    if (pPam)
+    {
+        IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+        pMarkAccess->deleteFieldmarkAt(*pPam->GetPoint());
+    }
+}
+
+SwHistoryTextFieldmark::SwHistoryTextFieldmark(const ::sw::mark::IFieldmark& rFieldMark)
+    : SwHistoryHint(HSTRY_TEXTFIELDMARK)
+    , m_sName(rFieldMark.GetName())
+    , m_sType(rFieldMark.GetFieldname())
+    , m_nNode(rFieldMark.GetMarkPos().nNode.GetIndex())
+    , m_nContent(rFieldMark.GetMarkPos().nContent.GetIndex())
+{
+}
+
+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));
+
+    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);
+    }
+}
+
+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));
+
+    if (pPam)
+    {
+        IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+        pMarkAccess->deleteFieldmarkAt(*pPam->GetPoint());
+    }
+}
 
 SwHistorySetAttrSet::SwHistorySetAttrSet( const SfxItemSet& rSet,
                         sal_uLong nNodePos, const std::set<sal_uInt16> &rSetArr )
diff --git a/sw/source/core/undo/unbkmk.cxx b/sw/source/core/undo/unbkmk.cxx
index fc465aad21b2..c4d77b6e2f71 100644
--- a/sw/source/core/undo/unbkmk.cxx
+++ b/sw/source/core/undo/unbkmk.cxx
@@ -148,4 +148,36 @@ void SwUndoRenameBookmark::RedoImpl(::sw::UndoRedoContext & rContext)
     Rename(rContext, m_sOldName, m_sNewName);
 }
 
+SwUndoInsNoTextFieldmark::SwUndoInsNoTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark)
+    : SwUndo(SwUndoId::INSERT, rFieldmark.GetMarkPos().GetDoc())
+    , m_pHistoryNoTextFieldmark(new SwHistoryNoTextFieldmark(rFieldmark))
+{
+}
+
+void SwUndoInsNoTextFieldmark::UndoImpl(::sw::UndoRedoContext & rContext)
+{
+    m_pHistoryNoTextFieldmark->ResetInDoc(&rContext.GetDoc());
+}
+
+void SwUndoInsNoTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext)
+{
+    m_pHistoryNoTextFieldmark->SetInDoc(&rContext.GetDoc(), false);
+}
+
+SwUndoInsTextFieldmark::SwUndoInsTextFieldmark(const ::sw::mark::IFieldmark& rFieldmark)
+    : SwUndo(SwUndoId::INSERT, rFieldmark.GetMarkPos().GetDoc())
+    , m_pHistoryTextFieldmark(new SwHistoryTextFieldmark(rFieldmark))
+{
+}
+
+void SwUndoInsTextFieldmark::UndoImpl(::sw::UndoRedoContext & rContext)
+{
+    m_pHistoryTextFieldmark->ResetInDoc(&rContext.GetDoc());
+}
+
+void SwUndoInsTextFieldmark::RedoImpl(::sw::UndoRedoContext & rContext)
+{
+    m_pHistoryTextFieldmark->SetInDoc(&rContext.GetDoc(), false);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index 65717add205e..c47ca12460bb 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -641,6 +641,9 @@ OUString GetUndoComment(SwUndoId eId)
         case SwUndoId::PARA_SIGN_ADD:
             pId = STR_PARAGRAPH_SIGN_UNDO;
             break;
+        case SwUndoId::INSERT_FORM_FIELD:
+            pId = STR_UNDO_INSERT_FORM_FIELD;
+            break;
     };
 
     assert(pId);
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index 56d4df1c119c..a91bd65084c1 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -74,6 +74,7 @@
 #include <MarkManager.hxx>
 #include <xmloff/odffields.hxx>
 #include <IDocumentContentOperations.hxx>
+#include <IDocumentUndoRedo.hxx>
 
 using namespace nsSwDocInfoSubType;
 
@@ -731,6 +732,8 @@ FIELD_INSERT:
 
             case FN_INSERT_TEXT_FORMFIELD:
             {
+                rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
                 SwPaM* pCursorPos = rSh.GetCursor();
                 if(pCursorPos)
                 {
@@ -745,26 +748,39 @@ FIELD_INSERT:
                         pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMTEXT);
                     }
                 }
+
+                rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+                rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
             }
             break;
             case FN_INSERT_CHECKBOX_FORMFIELD:
             {
+                rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
                 SwPaM* pCursorPos = rSh.GetCursor();
                 if(pCursorPos)
                 {
                     IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
                     pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMCHECKBOX);
                 }
+
+                rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+                rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
             }
             break;
             case FN_INSERT_DROPDOWN_FORMFIELD:
             {
+                rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+
                 SwPaM* pCursorPos = rSh.GetCursor();
                 if(pCursorPos)
                 {
                     IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
                     pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMDROPDOWN);
                 }
+
+                rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
+                rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
             }
             break;
             default:


More information about the Libreoffice-commits mailing list