diff options
author | Tamás Zolnai <tamas.zolnai@collabora.com> | 2019-03-09 14:44:50 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2019-03-18 10:16:12 +0100 |
commit | fbb148af3f175ad21bc5bea61a611c52e83f9eed (patch) | |
tree | deb12dc14329760c10ea7aadd06f2a8be73caa71 /sw | |
parent | df3a97ac7c430d50aba92d1a684d3e06005da5fd (diff) |
MSForms: Introduce a new IFieldMark for drop-down form field
* It was weird anyway that a drop-down form field was represented
as an CheckboxFieldmark.
* It will be useful for later commits, to have a separate field type
for drop-down field.
* Needed to fix-up the API a bit because it was designed to specify
the field type after initialization. I solved it in a way to not break
the API behavior. Hopefully it's not very slow.
Reviewed-on: https://gerrit.libreoffice.org/68960
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
(cherry picked from commit f66a83c95c21b4311918a64bb85016857b49f4d4)
Change-Id: I3103e6b1c36289b27b62ab9ca7dfeebc14901c8a
Reviewed-on: https://gerrit.libreoffice.org/69194
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/IDocumentMarkAccess.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/crsr/bookmrk.cxx | 33 | ||||
-rw-r--r-- | sw/source/core/doc/docbm.cxx | 50 | ||||
-rw-r--r-- | sw/source/core/inc/MarkManager.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/inc/bookmrk.hxx | 12 | ||||
-rw-r--r-- | sw/source/core/inc/unobookmark.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/text/itrform2.cxx | 4 | ||||
-rw-r--r-- | sw/source/core/unocore/unobkm.cxx | 23 |
8 files changed, 119 insertions, 8 deletions
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx index 823326e2b8ac..cbd523c012b1 100644 --- a/sw/inc/IDocumentMarkAccess.hxx +++ b/sw/inc/IDocumentMarkAccess.hxx @@ -47,6 +47,7 @@ class IDocumentMarkAccess ANNOTATIONMARK, TEXT_FIELDMARK, CHECKBOX_FIELDMARK, + DROPDOWN_FIELDMARK, NAVIGATOR_REMINDER }; @@ -255,6 +256,7 @@ class IDocumentMarkAccess virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0; virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0; + virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0; // Annotation Marks virtual const_iterator_t getAnnotationMarksBegin() const = 0; diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index 630bfe9c11d1..c80fb490aa1b 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -478,6 +478,39 @@ namespace sw { namespace mark pResult->second >>= bResult; return bResult; } + + DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM) + : Fieldmark(rPaM) + { + } + + DropDownFieldmark::~DropDownFieldmark() + { + } + + void DropDownFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode) + { + if (eMode == sw::mark::InsertMode::New) + { + lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT); + + // For some reason the end mark is moved from 1 by the Insert: + // we don't want this for checkboxes + SwPosition aNewEndPos = GetMarkEnd(); + aNewEndPos.nContent--; + SetMarkEndPos( aNewEndPos ); + } + else + { + lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT); + } + } + + void DropDownFieldmark::ReleaseDoc(SwDoc* const pDoc) + { + lcl_RemoveFieldMarks(this, pDoc, + CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT); + } }} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index ccc3d5382ffb..727655250a2e 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -338,6 +338,8 @@ IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk) return MarkType::TEXT_FIELDMARK; else if(*pMarkTypeInfo == typeid(CheckboxFieldmark)) return MarkType::CHECKBOX_FIELDMARK; + else if(*pMarkTypeInfo == typeid(DropDownFieldmark)) + return MarkType::DROPDOWN_FIELDMARK; else if(*pMarkTypeInfo == typeid(NavigatorReminder)) return MarkType::NAVIGATOR_REMINDER; else @@ -414,6 +416,9 @@ namespace sw { namespace mark case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK: pMark = std::shared_ptr<IMark>(new CheckboxFieldmark(rPaM)); break; + case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK: + pMark = std::shared_ptr<IMark>(new DropDownFieldmark(rPaM)); + break; case IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER: pMark = std::shared_ptr<IMark>(new NavigatorReminder(rPaM)); break; @@ -463,6 +468,7 @@ namespace sw { namespace mark break; case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK: case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK: + case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK: lcl_InsertMarkSorted(m_vFieldmarks, pMark); break; case IDocumentMarkAccess::MarkType::ANNOTATIONMARK: @@ -524,9 +530,20 @@ namespace sw { namespace mark bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified(); m_pDoc->getIDocumentState().SetEnableSetModified(false); - sw::mark::IMark* pMark = makeMark( rPaM, rName, - IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK, - sw::mark::InsertMode::New); + sw::mark::IMark* pMark = nullptr; + if(rType == ODF_FORMCHECKBOX) + { + pMark = makeMark( rPaM, rName, + IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK, + sw::mark::InsertMode::New); + } + else if(rType == ODF_FORMDROPDOWN) + { + pMark = makeMark( rPaM, rName, + IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK, + sw::mark::InsertMode::New); + } + sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark ); if (pFieldMark) pFieldMark->SetFieldname( rType ); @@ -939,6 +956,7 @@ namespace sw { namespace mark case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK: case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK: + case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK: { IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark); if ( ppFieldmark != m_vFieldmarks.end() ) @@ -1084,6 +1102,32 @@ namespace sw { namespace mark deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark)); } + ::sw::mark::IFieldmark* MarkManager::changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) + { + bool bActualChange = false; + if(rNewType == ODF_FORMDROPDOWN) + { + if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) + bActualChange = true; + } + else if(rNewType == ODF_FORMCHECKBOX) + { + if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) + bActualChange = true; + } + + if (!bActualChange) + return nullptr; + + // Store attributes needed to create the new fieldmark + OUString sName = pFieldmark->GetName(); + SwPaM aPaM(pFieldmark->GetMarkPos()); + + // Remove the old fieldmark and create a new one with the new type + deleteFieldmarkAt(*aPaM.GetPoint()); + return makeNoTextFieldBookmark(aPaM, sName, rNewType); + } + IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const { diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx index 7a3612bb6131..4544bae57b85 100644 --- a/sw/source/core/inc/MarkManager.hxx +++ b/sw/source/core/inc/MarkManager.hxx @@ -86,6 +86,7 @@ namespace sw { virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override; virtual void deleteFieldmarkAt(const SwPosition& rPos) override; + virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override; void dumpAsXml(struct _xmlTextWriter* pWriter) const; diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx index 6daa37d1d7e4..59089c846d43 100644 --- a/sw/source/core/inc/bookmrk.hxx +++ b/sw/source/core/inc/bookmrk.hxx @@ -234,6 +234,7 @@ namespace sw { virtual void ReleaseDoc(SwDoc* const pDoc) override; }; + /// Fieldmark representing a checkbox form field. class CheckboxFieldmark : virtual public ICheckboxFieldmark , public Fieldmark @@ -245,6 +246,17 @@ namespace sw { bool IsChecked() const override; void SetChecked(bool checked) override; }; + + /// Fieldmark representing a drop-down form field. + class DropDownFieldmark + : public Fieldmark + { + public: + DropDownFieldmark(const SwPaM& rPaM); + virtual ~DropDownFieldmark() override; + virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override; + virtual void ReleaseDoc(SwDoc* const pDoc) override; + }; } } #endif diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx index 7ec058e086bd..569cf8b8d5b3 100644 --- a/sw/source/core/inc/unobookmark.hxx +++ b/sw/source/core/inc/unobookmark.hxx @@ -67,6 +67,8 @@ protected: const ::sw::mark::IMark* GetBookmark() const; + IDocumentMarkAccess* GetIDocumentMarkAccess(); + void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase ); virtual ~SwXBookmark() override; diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 93f4aa72df4b..d0ddd033aef7 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -915,10 +915,6 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const { pPor = new SwFieldMarkPortion(); } - else - { - assert( false ); // unknown type... - } } } if( !pPor ) diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx index d3212fbbe245..7b2d93467316 100644 --- a/sw/source/core/unocore/unobkm.cxx +++ b/sw/source/core/unocore/unobkm.cxx @@ -124,6 +124,11 @@ const ::sw::mark::IMark* SwXBookmark::GetBookmark() const return m_pImpl->m_pRegisteredBookmark; } +IDocumentMarkAccess* SwXBookmark::GetIDocumentMarkAccess() +{ + return m_pImpl->m_pDoc->getIDocumentMarkAccess(); +} + SwXBookmark::SwXBookmark(SwDoc *const pDoc) : m_pImpl( new SwXBookmark::Impl(pDoc) ) { @@ -551,7 +556,21 @@ void SwXFieldmark::setFieldType(const OUString & fieldType) dynamic_cast<const IFieldmark*>(GetBookmark())); if(!pBkm) throw uno::RuntimeException(); - pBkm->SetFieldname(fieldType); + if(fieldType != getFieldType()) + { + if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX) + { + ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeNonTextFieldmarkType(pBkm, fieldType); + if (pNewFieldmark) + { + registerInMark(*this, pNewFieldmark); + return; + } + } + + // We did not generate a new fieldmark, so set the type ID + pBkm->SetFieldname(fieldType); + } } uno::Reference<container::XNameContainer> SwXFieldmark::getParameters() @@ -585,6 +604,8 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark, pXBkmk = new SwXFieldmark(false, &rDoc); else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark)) pXBkmk = new SwXFieldmark(true, &rDoc); + else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark)) + pXBkmk = new SwXFieldmark(true, &rDoc); else pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc); |