summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorTamás Zolnai <tamas.zolnai@collabora.com>2019-02-21 13:38:33 +0100
committerAndras Timar <andras.timar@collabora.com>2019-03-18 10:08:47 +0100
commit788c25b68fc48275eebd13e94f3bf81d5eb8c7bb (patch)
treedcf2c8b8a2194e935f205a772bd74b189edd16a6 /sw/source
parent4479eac3ce1a154c538b04165746ba993e981ed9 (diff)
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@collabora.com> (cherry picked from commit 55d6be75732d1bb0067bba9496c74ef30be9a3ec) Change-Id: I358c2704cb30212a38f8a998888a36f72fa404e5 Reviewed-on: https://gerrit.libreoffice.org/69190 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/core/doc/docbm.cxx34
-rw-r--r--sw/source/core/inc/MarkManager.hxx2
-rw-r--r--sw/source/core/inc/UndoBookmark.hxx27
-rw-r--r--sw/source/core/inc/rolbck.hxx29
-rw-r--r--sw/source/core/undo/rolbck.cxx90
-rw-r--r--sw/source/core/undo/unbkmk.cxx32
-rw-r--r--sw/source/core/undo/undobj.cxx3
-rw-r--r--sw/source/uibase/shells/textfld.cxx16
8 files changed, 233 insertions, 0 deletions
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: