Kaydet (Commit) 788c25b6 authored tarafından Tamás Zolnai's avatar Tamás Zolnai Kaydeden (comit) Andras Timar

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: 's avatarTamás Zolnai <tamas.zolnai@collabora.com>
(cherry picked from commit 55d6be75)

Change-Id: I358c2704cb30212a38f8a998888a36f72fa404e5
Reviewed-on: https://gerrit.libreoffice.org/69190Reviewed-by: 's avatarAndras Timar <andras.timar@collabora.com>
Tested-by: 's avatarAndras Timar <andras.timar@collabora.com>
üst 4479eac3
......@@ -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;
......
......@@ -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")
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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: */
......@@ -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;
......
......@@ -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 )
......
......@@ -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: */
......@@ -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);
......
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment